/
load.s
157 lines (113 loc) · 2.63 KB
/
load.s
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
148
149
150
151
152
153
154
155
156
; load.s
; entry is from boot.s
bits 64
; Everywhere you see some weird addition logic
; This is to fit the addresses into 32 bit sizes
; Note, they will sign extend!
section .text
; include useful definitions
%include "defines.mac"
; extern to kmain.d
extern kmain
extern apEntry
global start64
start64:
; Initialize the 64 bit stack pointer.
mov rsp, ((_stack - KERNEL_VMA_BASE) + STACK_SIZE)
; Set up the stack for the return.
push CS_KERNEL
; RAX - the address to return to
mov rax, KERNEL_VMA_BASE >> 32
shl rax, 32
or rax, long_entry - (KERNEL_VMA_BASE & 0xffffffff00000000)
push rax
; Go into canonical higher half
; It uses a trick to update the program counter
; across a 64 bit address space
ret
long_entry:
; From here on out, we are running instructions
; within the higher half (0xffffffff80000000 ... )
; We can safely upmap the lower half, we do not
; need an identity mapping of this region
; set up a 64 bit virtual stack
mov rax, KERNEL_VMA_BASE >> 32
shl rax, 32
or rax, _stack - (KERNEL_VMA_BASE & 0xffffffff00000000)
mov rsp, rax
; set cpu flags
push 0
lss eax, [rsp]
popf
; set the input/output permission level to 3
; it will allow all access
pushf
pop rax
or rax, 0x3000
push rax
popf
; update the multiboot struct to point to a
; virtual address
add rsi, (KERNEL_VMA_BASE & 0xffffffff)
; push the parameters (just in case)
push rsi
push rdi
; clear rbp
xor rbp, rbp
; call kmain
call kmain
; we should not get here
haltloop:
hlt
jmp haltloop
nop
nop
nop
global start64_ap
start64_ap:
; Initialize the 64 bit stack pointer.
mov rsp, ((_stack - KERNEL_VMA_BASE) + STACK_SIZE)
; Set up the stack for the return.
push CS_KERNEL
; RAX - the address to return to
mov rax, KERNEL_VMA_BASE >> 32
shl rax, 32
or rax, long_entry_ap - (KERNEL_VMA_BASE & 0xffffffff00000000)
push rax
; Go into canonical higher half
; It uses a trick to update the program counter
; across a 64 bit address space
ret
long_entry_ap:
; From here on out, we are running instructions
; within the higher half (0xffffffff80000000 ... )
; We can safely upmap the lower half, we do not
; need an identity mapping of this region
; set up a 64 bit virtual stack
mov rax, KERNEL_VMA_BASE >> 32
shl rax, 32
or rax, _stack - (KERNEL_VMA_BASE & 0xffffffff00000000)
mov rsp, rax
; set cpu flags
push 0
lss eax, [rsp]
popf
; set the input/output permission level to 3
; it will allow all access
pushf
pop rax
or rax, 0x3000
push rax
popf
; clear rbp
xor rbp, rbp
; call kmain
call apEntry
; end
; stack space
global _stack
align 4096
_stack:
%rep STACK_SIZE
dd 0
%endrep