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
|
global start
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 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 ebx
mov edi, 0x1000
mov cr3, edi
xor eax, eax
mov ecx, 4096
rep stosd
mov edi, cr3
mov DWORD [edi], 0x2003 ; Set the uint32_t at the destination index to 0x2003.
add edi, 0x1000 ; Add 0x1000 to the destination index.
mov DWORD [edi], 0x3003 ; Set the uint32_t at the destination index to 0x3003.
add edi, 0x1000 ; Add 0x1000 to the destination index.
mov DWORD [edi], 0x4003 ; Set the uint32_t at the destination index to 0x4003.
add edi, 0x1000 ; 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:
call amd64_shim
push rax
call kmain
cli
halt:
hlt
jmp halt
|