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
22
22
data_start = .;
23
23
.rodata : { *(.rodata .rodata.*) } :ram
24
24
.text : { *(.text .text.*) }
25
+ .text32 : { *(.text32) }
25
26
.data : { *(.data .data.*) }
26
27
data_size = . - data_start;
27
28
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" ) ) ;
1
2
global_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