File tree Expand file tree Collapse file tree 4 files changed +81
-0
lines changed Expand file tree Collapse file tree 4 files changed +81
-0
lines changed Original file line number Diff line number Diff line change @@ -22,6 +22,7 @@ SECTIONS
2222 data_start = .;
2323 .rodata : { *(.rodata .rodata .*) } :ram
2424 .text : { *(.text .text .*) }
25+ .text32 : { *(.text32 ) }
2526 .data : { *(.data .data .*) }
2627 data_size = . - data_start;
2728
Original file line number Diff line number Diff line change 1+ .section .rodata, "a"
2+
3+ gdt64_ptr:
4+ .short gdt64_end - gdt64_start - 1 # GDT length is actually (length - 1)
5+ .quad gdt64_start
6+
7+ gdt64_start: # First descriptor is always null
8+ .quad 0
9+ code64_desc: # 64-bit Code-Segments always have: Base = 0, Limit = 4G
10+ # CS.Limit[15:00] = 0 - Ignored
11+ .short 0x0000
12+ # CS.Base[15:00] = 0 - Ignored
13+ .short 0x0000
14+ # CS.Base[23:16] = 0 (bits 0-7) - Ignored
15+ .byte 0x00
16+ # CS.Accessed = 1 (bit 8) - Don't write to segment on first use
17+ # CS.ReadEnable = 1 (bit 9) - Read/Execute Code-Segment
18+ # CS.Conforming = 0 (bit 10) - Nonconforming, no lower-priv access
19+ # CS.Executable = 1 (bit 11) - Code-Segement
20+ # CS.S = 1 (bit 12) - Not a System-Segement
21+ # CS.DPL = 0 (bits 13-14) - We only use this segment in Ring 0
22+ # CS.P = 1 (bit 15) - Segment is present
23+ .byte 0b10011011
24+ # CS.Limit[19:16] = 0 (bits 16-19) - Ignored
25+ # CS.AVL = 0 (bit 20) - Our software doesn't use this bit
26+ # CS.L = 1 (bit 21) - This isn't a 64-bit segment
27+ # CS.D = 0 (bit 22) - This is a 32-bit segment
28+ # CS.G = 0 (bit 23) - Ignored
29+ .byte 0b00100000
30+ # CS.Base[31:24] = 0 (bits 24-31) - Ignored
31+ .byte 0x00
32+ gdt64_end:
Original file line number Diff line number Diff line change 1+ global_asm ! ( include_str!( "ram32.s" ) ) ;
12global_asm ! ( include_str!( "ram64.s" ) ) ;
3+ global_asm ! ( include_str!( "gdt64.s" ) ) ;
Original file line number Diff line number Diff line change 1+ .section .text32, "ax"
2+ .code32
3+
4+ ram32_start:
5+ # Stash the PVH start_info struct in %rdi.
6+ movl %ebx , %edi
7+ # Zero out %rsi, its value is unspecificed in the PVH Boot Protocol.
8+ xorl %esi , %esi
9+
10+ setup_page_tables:
11+ # First L2 entry identity maps [0, 2 MiB)
12+ movl $0b10000011 , (L2_TABLES) # huge (bit 7), writable (bit 1), present (bit 0)
13+ # First L3 entry points to L2 table
14+ movl $L2_TABLES, %eax
15+ orb $0b00000011 , %al # writable (bit 1), present (bit 0)
16+ movl %eax , (L3_TABLE)
17+ # First L4 entry points to L3 table
18+ movl $L3_TABLE, %eax
19+ orb $0b00000011 , %al # writable (bit 1), present (bit 0)
20+ movl %eax , (L4_TABLE)
21+
22+ enable_paging:
23+ # Load page table root into CR3
24+ movl $L4_TABLE, %eax
25+ movl %eax , %cr3
26+
27+ # Set CR4.PAE (Physical Address Extension)
28+ movl %cr4 , %eax
29+ orb $0b00100000 , %al # Set bit 5
30+ movl %eax , %cr4
31+ # Set EFER.LME (Long Mode Enable)
32+ movl $0xC0000080 , %ecx
33+ rdmsr
34+ orb $0b00000001 , %ah # Set bit 8
35+ wrmsr
36+ # Set CRO.PG (Paging)
37+ movl %cr0 , %eax
38+ orl $(1 << 31 ), %eax
39+ movl %eax , %cr0
40+
41+ jump_to_64bit:
42+ # We are now in 32-bit compatibility mode. To enter 64-bit mode, we need to
43+ # load a 64-bit code segment into our GDT.
44+ lgdtl gdt64_ptr
45+ # Set CS to a 64-bit segment and jump to 64-bit code.
46+ ljmpl $(code64_desc - gdt64_start), $ram64_start
You can’t perform that action at this time.
0 commit comments