-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkernel.s
162 lines (142 loc) · 3.25 KB
/
kernel.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
157
158
159
160
161
162
; Port communication via mapped memory
global outb
; outb - send a byte to an I/O port
; stack: [esp+8] the data bytes
; [esp+4] the I/O port
; [esp ] return address
outb:
mov al, [esp+8] ; move the data to be sent into the al register
mov dx, [esp+4] ; move the address of the I/O port to the dx register
out dx, al ; send the data to the I/O port
ret ; return to the calling function
; Loads GDT table using lgdt and performas jump to code segment
global gdt_flush
; gdt_flush - load the GTD table
; stack:
; [esp + 4] = pointer to gdt_ptr_struct
gdt_flush:
mov eax, [esp + 4]
lgdt[eax]
mov ax, 0x10 ; point all data registers at data segment entry in GDT at 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x08:.flush ; jump to code segment entry at 0x08
.flush:
ret
global idt_flush ; Allows the C code to call idt_flush().
idt_flush:
mov eax, [esp+4] ; Get the pointer to the IDT, passed as a parameter.
lidt [eax] ; Load the IDT pointer.
ret
; Interrupt Service Request Handles
; We define 2 macro's: one for exceptions that do not push an error code
; and one for exceptions that do push an error code
; NASM will convert these to the 32 appropriate code entries
%macro ISR_NOERRORCODE 1
global isr%1
isr%1:
push byte 0 ; push a dummy error code
push byte %1 ; push the interrup number
jmp alltraps
%endmacro
%macro ISR_WITHERRORCODE 1
global isr%1
isr%1:
push byte %1 ; only push interrupt number, error code has already been pushed
jmp alltraps
%endmacro
; This macro creates a stub for an IRQ - the first parameter is
; the IRQ number, the second is the ISR number it is remapped to.
%macro IRQ 2
global irq%1
irq%1:
push byte 0
push byte %2
jmp alltraps
%endmacro
; now use the macro's to define the right handlers
ISR_NOERRORCODE 0
ISR_NOERRORCODE 1
ISR_NOERRORCODE 2
ISR_NOERRORCODE 3
ISR_NOERRORCODE 4
ISR_NOERRORCODE 5
ISR_NOERRORCODE 6
ISR_NOERRORCODE 7
ISR_WITHERRORCODE 8
ISR_NOERRORCODE 9
ISR_WITHERRORCODE 10
ISR_WITHERRORCODE 11
ISR_WITHERRORCODE 12
ISR_WITHERRORCODE 13
ISR_WITHERRORCODE 14
ISR_NOERRORCODE 15
ISR_NOERRORCODE 16
ISR_WITHERRORCODE 17
ISR_NOERRORCODE 18
ISR_NOERRORCODE 19
ISR_NOERRORCODE 20
ISR_NOERRORCODE 21
ISR_NOERRORCODE 22
ISR_NOERRORCODE 23
ISR_NOERRORCODE 24
ISR_NOERRORCODE 25
ISR_NOERRORCODE 26
ISR_NOERRORCODE 27
ISR_NOERRORCODE 28
ISR_NOERRORCODE 29
ISR_NOERRORCODE 30
ISR_NOERRORCODE 31
IRQ 0, 32
IRQ 1, 33
IRQ 2, 34
IRQ 3, 35
IRQ 4, 36
IRQ 5, 37
IRQ 6, 38
IRQ 7, 39
IRQ 8, 40
IRQ 9, 41
IRQ 10, 42
IRQ 11, 43
IRQ 12, 44
IRQ 13, 45
IRQ 14, 46
IRQ 15, 47
ISR_NOERRORCODE 64 ;this is T_SYSCALL
; In isr.c
extern trap
;extern irq_handler
; This is our common ISR stub. It saves the processor state, sets
; up for kernel mode segments, calls the C-level fault handler,
; and finally restores the stack frame.
alltraps:
; Build trap frame.
push ds
push es
push fs
push gs
pusha
; Set up data and per-cpu segments.
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
; Call trap(tf), where tf=%esp
push esp
call trap
add esp, 4
; Return falls through to trapret...
global trapret
trapret:
popa
pop gs
pop fs
pop es
pop ds
add esp, 0x8 ; trapno and errcode
iret