+ jc panic
+ cli # BIOS might have enabled interrupts
+ addl $1024, %eax # Total kB memory
+ cmp $0x10000, %eax # Cap at 64 MB
+ jbe 1f
+ mov $0x10000, %eax
+1: shrl $2, %eax # Total 4 kB pages
+ movl %eax, ram_pgs
+
+#### Create temporary page directory and page table and set page
+#### directory base register.
+
+# Create page directory at 64 kB and fill with zeroes.
+ mov $0x1000, %ax
+ mov %ax, %es
+ subl %eax, %eax
+ subl %edi, %edi
+ movl $0x400, %ecx
+ rep stosl
+
+# Add PDEs to point to PTEs for the first 64 MB of RAM.
+# Also add identical PDEs starting at LOADER_PHYS_BASE.
+# See [IA32-v3a] section 3.7.6 "Page-Directory and Page-Table Entries"
+# for a description of the bits in %eax.
+
+
+ movl $0x11007, %eax
+ movl $0x11, %ecx
+ subl %edi, %edi
+1: movl %eax, %es:(%di)
+ movl %eax, %es:LOADER_PHYS_BASE >> 20(%di)
+ addw $4, %di
+ addl $0x1000, %eax
+ loop 1b
+
+# Set up one-to-map linear to physical map for the first 64 MB of RAM.
+# See [IA32-v3a] section 3.7.6 "Page-Directory and Page-Table Entries"
+# for a description of the bits in %eax.
+
+ movw $0x1100, %ax
+ movw %ax, %es
+ movl $0x7, %eax
+ movl $0x4000, %ecx
+ subl %edi, %edi
+1: movl %eax, %es:(%di)
+ addw $4, %di
+ addl $0x1000, %eax
+ loop 1b
+
+# Set page directory base register.
+
+ movl $0x10000, %eax
+ movl %eax, %cr3
+
+#### Switch to protected mode.
+
+# Note that interrupts are still off.
+
+# Point the GDTR to our GDT. Protected mode requires a GDT.
+# We need a data32 prefix to ensure that all 32 bits of the GDT
+# descriptor are loaded (default is to load only 24 bits).
+
+ data32 lgdt gdtdesc
+
+# Then we turn on the following bits in CR0:
+# PE (Protect Enable): this turns on protected mode.
+# PG (Paging): turns on paging.
+# WP (Write Protect): if unset, ring 0 code ignores
+# write-protect bits in page tables (!).
+# EM (Emulation): forces floating-point instructions to trap.
+# We don't support floating point.