1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
global start
global kernel_pml4
global kernel_pdpt_0
global kernel_pd_0
global kernel_pt_0
global paging_pt
global bootstrap_pt
extern kmain
extern amd64_shim
bits 32
section .multiboot
align 8
mb_start:
; header
dd 0xe85250d6
dd 0
dd mb_end - mb_start
dd 0x100000000 - (0xe85250d6 + (mb_end - mb_start))
; null tag
dw 0
dw 0
dd 8
;
mb_end:
section .bss
align 4096
kernel_pml4: ; reserve memory for initial 512 pml4 entires
resb 4096
kernel_pdpt_0: ; reserve memory for initial 512 pdpt entires
resb 4096
kernel_pd_0: ; reserve memory for initial 512 pd entries
resb 4096
kernel_pt_0: ; reserve memory for initial 512 pt entries
resb 4096
paging_pt: ; reserve pages for pager mappings
resb 4096
bootstrap_pt: ; reserve pages to bootstrap pager
resb 4096
align 16
stack_start:
resb 16384
stack_end:
section .rodata
align 16
; Access bits
PRESENT equ 1 << 7
NOT_SYS equ 1 << 4
EXEC equ 1 << 3
DC equ 1 << 2
RW equ 1 << 1
ACCESSED equ 1 << 0
; Flags bits
GRAN_4K equ 1 << 7
SZ_32 equ 1 << 6
LONG_MODE equ 1 << 5
GDT:
.Null: equ $ - GDT
dq 0
.Code: equ $ - GDT
dd 0xFFFF ; Limit & Base (low, bits 0-15)
db 0 ; Base (mid, bits 16-23)
db PRESENT | NOT_SYS | EXEC | RW ; Access
db GRAN_4K | LONG_MODE | 0xF ; Flags & Limit (high, bits 16-19)
db 0 ; Base (high, bits 24-31)
.Data: equ $ - GDT
dd 0xFFFF ; Limit & Base (low, bits 0-15)
db 0 ; Base (mid, bits 16-23)
db PRESENT | NOT_SYS | RW ; Access
db GRAN_4K | SZ_32 | 0xF ; Flags & Limit (high, bits 16-19)
db 0 ; Base (high, bits 24-31)
.TSS: equ $ - GDT
dd 0x00000068
dd 0x00CF8900
.Pointer:
dw $ - GDT - 1
dq GDT
section .text
align 8
start:
cli
mov esp, stack_end
mov ebp, stack_end
push DWORD 0
push ebx
mov edi, 0x1000
mov cr3, edi
xor eax, eax
mov ecx, 4096
rep stosd
mov edi, cr3
mov DWORD [edi], kernel_pdpt_0 + 3 ; Set the uint32_t at the destination index to 0x2003.
mov edi, kernel_pdpt_0 ; Add 0x1000 to the destination index.
mov DWORD [edi], kernel_pd_0 + 3 ; Set the uint32_t at the destination index to 0x3003.
mov edi, kernel_pd_0 ; Add 0x1000 to the destination index.
mov DWORD [edi], kernel_pt_0 + 3 ; Set the uint32_t at the destination index to 0x4003.
mov edi, kernel_pt_0 ; Add 0x1000 to the destination index.
mov ebx, 0x00000003 ; Set the B-register to 0x00000003.
mov ecx, 512 ; Set the C-register to 512.
.SetEntry:
mov DWORD [edi], ebx ; Set the uint32_t at the destination index to the B-register.
add ebx, 0x1000 ; Add 0x1000 to the B-register.
add edi, 8 ; Add eight to the destination index.
loop .SetEntry ; Set the next entry.
;push ebx ; Call our function to set up basic paging
;call amd64_shim
mov eax, cr4 ; Enable the PAE bit
or eax, 1 << 5
mov cr4, eax
mov ecx, 0xC0000080 ; Enable long mode
rdmsr
or eax, 1 << 8
wrmsr
mov eax, cr0 ; Enable paging
or eax, 1 << 31
mov cr0, eax
lgdt [GDT.Pointer]
jmp GDT.Code:code64
bits 64
code64:
pop rdi
call amd64_shim
mov rdi, rax
call kmain
cli
halt:
hlt
jmp halt
|