-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmpinit.S
151 lines (119 loc) · 3.17 KB
/
mpinit.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
/*****************************************************************************/
/* File: mp_init.S */
/* */
/* Description: Startup code for AP. */
/* */
/* Author: Shoily O Rahman <[email protected]> */
/* */
/* Date: Aug 9, 2020 */
/* */
/*****************************************************************************/
.include "krnlconst.S"
.code16
.text
.globl _start
_start:
cli
xorw %ax, %ax
movw %ax, %ss
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
// loads gdt
xorw %ax, %ax
movw %ax, %ds
lgdt gdtdescriptor
// turn on protected mode
movl %cr0, %eax
orl $1, %eax
movl %eax, %cr0
// jump to protected mode
ljmpl *protectmodecodesegaddr
// protected mode code
.code32
protectedmodeaddress:
movl $data_seg, %eax
movl %eax, %ds
movl %eax, %es
movl %eax, %ss
movl %eax, %fs
movl %eax, %gs
// get LAPIC id
movl AP_LAPIC_BASE_REGISTER, %ebx
addl $0x20, %ebx
movl (%ebx), %eax
shrl $24, %eax
movl %eax, %ecx
// GS register holds APIC ID
movl %ecx, %gs
// calculate start of kernel mode stack for this processor
movl $KERNEL_STACK_SIZE, %ebx
mull %ebx
movl AP_FIRST_STACK, %ebx
addl %ebx, %eax
// initialize protected mode stack
movl %eax, %esp
movl %esp, %ebp
// turning on paging
movl %ecx, %eax
movl $PAGE_SIZE, %ebx
mull %ebx
movl AP_KERNEL_PG_DIR, %ebx
addl %ebx, %eax
movl %eax, %cr3
movl %cr0, %ebx
orl $0x80000000, %ebx
movl %ebx, %cr0
ljmpl *highcodesegaddr
.code32
.section ".high", "ax"
highaddress:
// eax contains PGD
// clear TLB entries for 0x7C00
invlpg (0x7000)
// clear identity mapping for first 4MB
//addl $KERNEL_VIRT_ADDR, %eax
leal KERNEL_VIRT_ADDR(%eax), %ebx
movl $0, (%ebx)
// push lapic id in the stack
pushl %ecx
movl AP_FINISH_CODE+KERNEL_VIRT_ADDR, %eax
// call finish_mp_initialization
call *%eax
loop:
jmp loop
.data
// global descriptor table (GDT)
.p2align 5
gdt:
// offset 0x0 - NULL descriptor
.quad 0
code_seg_addr:
// offset 0x8 - cs should point to this descriptor
.word 0xFFFF
.word 0
.byte 0
.byte 0x9A
.byte 0xCF
.byte 0
data_seg_addr:
// offset 0x10 - ds, ss, es, fs, and gs should point to this descriptor
.word 0xFFFF
.word 0
.byte 0
.byte 0x92
.byte 0xCF
.byte 0
end_of_gdt:
protectmodecodesegaddr:
.long protectedmodeaddress
.word code_seg
highcodesegaddr:
.long highaddress
.word code_seg
gdtdescriptor:
.word end_of_gdt-gdt-1
.long gdt
.equ code_seg, code_seg_addr-gdt
.equ data_seg, data_seg_addr-gdt