Skip to content

Commit 53b9635

Browse files
committed
rom: Enter protected mode exactly how the SDM says
Also gets rid of any issues with the reset vector code overflowing. Signed-off-by: Joe Richey <joerichey@google.com>
1 parent 1b2291a commit 53b9635

File tree

1 file changed

+14
-12
lines changed

1 file changed

+14
-12
lines changed

src/asm/rom.s

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,28 +64,30 @@ rom32_start:
6464
jmpl *%eax
6565

6666
.code16
67-
rom16_protected:
68-
# We are now in 16-bit protected mode, To enter 32-bit protected mode, we
67+
rom16:
68+
# Order of instructions from Intel SDM 9.9.1 "Switching to Protected Mode"
69+
# Step 1: Disable interrupts
70+
cli
71+
72+
# Step 2: Load the GDT
73+
# We are currently in 16-bit real mode. To enter 32-bit protected mode, we
6974
# need to load 32-bit code/data segments into our GDT. The gdt32 in ROM is
7075
# at too high of an address (4 GiB - offset) for the data segment to reach.
7176
# So, we load gdt32 via the 16-bit code segement, using a 16-bit address.
7277
movw $gdt32_ptr_addr16, %bx
7378
lgdtl %cs:(%bx)
7479

75-
# Set CS to a 32-bit segment and jump to 32-bit code.
76-
ljmpl $(code32_desc - gdt32_start), $rom32_addr32
77-
78-
.align 16
79-
reset_vector: # 0xffff_fff0
80-
# This code must be 16 bytes or less, so be careful when adding anyting.
81-
cli
82-
83-
# Set CRO.PE (Protected Mode Enable)
80+
# Step 3: Set CRO.PE (Protected Mode Enable)
8481
movl %cr0, %eax
8582
orb $0b00000001, %al # Set bit 0
8683
movl %eax, %cr0
8784

88-
jmp rom16_protected
85+
# Step 4: Far JMP to change execution flow and serializes the processor.
86+
# Set CS to a 32-bit segment and jump to 32-bit code.
87+
ljmpl $(code32_desc - gdt32_start), $rom32_addr32
8988

9089
.align 16
90+
reset_vector: # 0xffff_fff0
91+
jmp rom16
92+
.align 16
9193
rom_end: # 0x1_0000_0000

0 commit comments

Comments
 (0)