-
Notifications
You must be signed in to change notification settings - Fork 12
/
kernel.asm
195 lines (154 loc) · 3.97 KB
/
kernel.asm
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
org 0x10FF0
bits 32
jmp Stage3
; Print green background
; mov ah, 0bh
; mov bh, 00h
; mov bl, 0ffh
; int 0x10
;******************************************************
; ENTRY POINT FOR STAGE 3
;******************************************************
; Welcome to the 32 bit world!
%include "mm.inc"
%include "stdio32.inc"
%include "pic.inc"
%include "pit.inc"
WelcomeMsg db "Welcome to Tu's Operating System", 0ah, 0h
InterruptMsg db "Interrupting", 0ah, 0h
GoodbyeMsg db "See ya later", 0ah, 0h
%define IA32_SYSENTER_CS 0x174
%define IA32_SYSENTER_ESP 0x175
%define IA32_SYSENTER_EIP 0x176
sysenter_setup:
; MSR[ECX] <- EDX:EAX
; Writes the contents of registers EDX:EAX into the 64-bit model specific
; register (MSR) speci- fied in the ECX register. The high-order 32 bits are
; copied from EDX and the low-order 32 bits are copied from EAX. Always set
; the undefined or reserved bits in an MSR to the values previ- ously read.
mov eax, 0x8 ; kernel code descriptor
mov edx, 0
mov ecx, IA32_SYSENTER_CS
wrmsr
mov eax, esp
mov edx, 0
mov ecx, IA32_SYSENTER_ESP
wrmsr
mov eax, Sysenter_Entry
mov edx, 0
mov ecx, IA32_SYSENTER_EIP
wrmsr
ret
Sysenter_Entry:
; VERY IMPORTANT if we want interrupt to function, since sysenter clear IF bit
; in EFLAGS register.
sti
mov bx, 0x10 ; set data segments to data selector (0x10)
mov ds, bx
; sysenter jumps here, is is executing this code at prividege level 0. Simular to Call Gates, normally we will
; provide a single entry point for all system calls.
cmp eax, 0
je clrscr
cmp eax, 1
je monitor_out
cmp eax, 2
je test_intr_kernel_space
cmp eax, 3
je test_intr_pic
cmp eax, 4
je STOP
; mov eax, GoodbyeMsg
; call Puts32
syscall_exit:
; restore back the stack for userspace afterward
mov bx, 0x23
mov ds, bx
sysexit
Stage3:
; get boot_info from BIOS
pop ecx
;-------------------------------;
; Set registers ;
;-------------------------------;
mov ax, 0x10 ; set data segments to data selector (0x10)
mov ds, ax
mov ss, ax
mov es, ax
mov esp, 90000h ; stack begins from 90000h
mov edi, 0xFFFFFFFF ; test 32 bit
call ClrScr32
mov eax, ecx
call phys_mem_manager_init
xchg bx, bx
mov edi, 0
call 0x40:0
call sysenter_setup
call MapPIC
call EnablePIT
;-------------------------------;
; Install our IDT ;
;-------------------------------;
call 0x30:0 ; install our IDT
mov bl, 0
mov bh, 24
call MovCur
mov eax, WelcomeMsg
call Puts32
; AMAZING
; Link to read for understanding: http://www.jamesmolloy.co.uk/tutorial_html/10.-User%20Mode.html
cli
mov ax,0x23
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax ;we don't need to worry about SS. it's handled by iret
mov eax, esp
push 0x23 ; user data segment with bottom 2 bits set for ring 3
push eax ; push our current stack just for the heck of it
pushf
push 0x1b; ;user code segment with bottom 2 bits set for ring 3
push 0xFF0 ; offset address
iret
;*******************************************************
; Stop execution
;*******************************************************
monitor_out:
; use kernel data segment, not userspace
; we must explicitly set, otherwise when we are trying to retrieve the
; data, 0x23 is used with eax for indexing instead.
; mov ax, 0x10 ; set data segments to data selector (0x10)
; mov ds, ax
mov bl, 0
mov bh, 25
call MovCur
mov eax, GoodbyeMsg
call Puts32
; restore back the stack for userspace afterward
; mov ax, 0x23
; mov ds, ax
jmp syscall_exit
clrscr:
; call ClrScr32
jmp syscall_exit
test_intr_kernel_space:
; mov ecx, 1
; int 1
; ; push syscall_exit
; mov ecx, 0
; mov ax, 3
; mov dl, 0
; div dl
; mov ax, 0x10 ; set data segments to data selector (0x10)
; mov ds, ax
; mov bl, 5
; mov bh, 5
; call MovCur
; mov eax, InterruptMsg
; call Puts32
jmp syscall_exit
test_intr_pic:
jmp syscall_exit
STOP:
; call ClrScr32
cli
hlt