Skip to content

Commit 90d675c

Browse files
committed
Automatic commit Sat Apr 23 02:10:42 PM EEST 2022
1 parent c57517e commit 90d675c

File tree

19 files changed

+1460
-3
lines changed

19 files changed

+1460
-3
lines changed

os/part3/kernel/video.asm

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,6 @@ Print_hex:
8484
; ah: Color attributes ;
8585
;**********************************************************************************;
8686
push r10
87-
push rbp
88-
mov rbp, rsp
8987
sub rsp, 20 ; make space for the string length (2 bytes) and 18 characters
9088
mov rsi, rsp
9189
push rsi ; store rsi (string address)
@@ -108,6 +106,6 @@ Print_hex:
108106
loop .digit
109107
pop rsi ; restore rsi (string address)
110108
call Print
111-
leave
109+
add rsp, 20
112110
pop r10
113111
ret

os/part3/os.bin

0 Bytes
Binary file not shown.

os/part4/.gdb_history

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
c
2+
q

os/part4/Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.PHONY: clean, .force-rebuild
2+
all: bootloader.bin
3+
4+
bootloader.bin: os.asm .force-rebuild
5+
nasm -fbin os.asm -o os.bin
6+
7+
clean:
8+
rm *.bin

os/part4/kernel/idt.asm

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
;**************************************************************************************;
2+
; Interrupt Descriptor Table (IDT) ;
3+
;**************************************************************************************;
4+
; The Interrupt Descriptor Table (IDT) is a data structure used to implement an ;
5+
; Interrupt Vector Table (IVT), i.e. to determine the proper response to three types ;
6+
; of events: hardware interrupts, software interrupts, and processor exceptions. ;
7+
; The IDT consists of 256 interrupt vectors, the first 32 (0–31 or 0x00–0x1F) of which ;
8+
; are used for processor exceptions. ;
9+
;**************************************************************************************;
10+
11+
BASE_OF_SECTION equ 0x8000
12+
13+
; We use a macro to simplify a little each IDT entry
14+
%macro .idtentry 3
15+
dw ((BASE_OF_SECTION + %1 - $$) & 0xFFFF) - 1024 ; Low word bits (0-15) of offset
16+
dw %2 ; Code-Segment-Selector
17+
db 0 ; Always zero
18+
db %3 ; Type and Attributes
19+
dw ((BASE_OF_SECTION + %1 - $$) >> 16) & 0xFFFF ; Middle bits (16-31) of offset
20+
dd ((BASE_OF_SECTION + %1 - $$) >> 32) & 0xFFFFFFFF ; High bits (32-64) of offset
21+
dd 0 ; Reserved
22+
%endmacro
23+
24+
IDT_START:
25+
;*************************************************************************************
26+
; IDT Entry: Address of Interrupt Service Routine, Code Segment Selector, Attributes ;
27+
;*************************************************************************************
28+
.idtentry ISR_Division_by_Zero, CODE_SEG, 0x8F ;0 (Divide by zero)
29+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;1 (Debug Exception)
30+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;2 (NMI, Non-Maskable Interrupt)
31+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;3 (Breakpoint Exception)
32+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;4 (INTO Overflow)
33+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;5 (Out of Bounds)
34+
.idtentry ISR_Invalid_Opcode , CODE_SEG, 0x8F ;6 (Invalid Opcode)
35+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;7 (Device Not Available)
36+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;8 (Double Fault)
37+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;9 (Deprecated)
38+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;10 (Invalid TSS)
39+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;11 (Segment Not Present)
40+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;12 (Stack-Segment Fault)
41+
.idtentry ISR_GPF , CODE_SEG, 0x8F ;13 (General Protection Fault)
42+
.idtentry ISR_Page_Fault , CODE_SEG, 0x8F ;14 (Page Fault)
43+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;15 (Reserved)
44+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;16 (x87 Floating-Point Exception)
45+
.idtentry ISR_Alignment_Check , CODE_SEG, 0x8F ;17 (Alignment Check Exception)
46+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;18 (Machine Check Exception)
47+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;19 (SIMD Floating-Point Exception)
48+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;20 (Virtualization Exception)
49+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;21 (Control Protection Exception)
50+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;22 (Reserved)
51+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;23 (Reserved)
52+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;24 (Reserved)
53+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;25 (Reserved)
54+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;26 (Reserved)
55+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;27 (Reserved)
56+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;28 (Hypervisor Injection Exception)
57+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;29 (VMM Communication Exception)
58+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;30 (Security Exception)
59+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;31 (Reserved)
60+
.idtentry ISR_systimer , CODE_SEG, 0x8E ;32 (IRQ0: Programmable Interrupt Timer)
61+
.idtentry ISR_keyboard , CODE_SEG, 0x8E ;33 (IRQ1: Keyboard)
62+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;34 (IRQ2: PIC Cascade, used internally)
63+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;35 (IRQ3: COM2, if enabled)
64+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;36 (IRQ4: COM1, if enabled)
65+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;37 (IRQ5: LPT2, if enabled)
66+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;38 (IRQ6: Floppy Disk)
67+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;39 (IRQ7: LPT1)
68+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;40 (IRQ8: CMOS real-time clock)
69+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;41 (IRQ9: Free)
70+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;42 (IRQ10: Free)
71+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;43 (IRQ11: Free)
72+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;44 (IRQ12: PS2 Mouse)
73+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;45 (IRQ13: Coprocessor)
74+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;46 (IRQ14: Primary ATA Hard Disk)
75+
.idtentry ISR_dummy , CODE_SEG, 0x8F ;47 (IRQ15: Secondary ATA Hard Disk)
76+
; ...
77+
; Although the IDT can contain less than 256 entries, any entries that are not present
78+
; will generate a General Protection Fault when an attempt to access them is made.
79+
IDT_END:
80+
81+
82+
; The IDTR is the argument for the LIDT assembly instruction
83+
; which loads the location of the IDT to the IDT Register.
84+
ALIGN 4
85+
IDTR:
86+
.Length dw IDT_END-IDT_START-1 ; One less than the size of the IDT in bytes.
87+
.Base dd IDT_START ; The linear address of the Interrupt Descriptor Table
88+
; (not the physical address, paging applies).

os/part4/kernel/isr.asm

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
; INTERRUPT SERVICE ROUTINES
2+
3+
BITS 64
4+
5+
;---Initialized data----------------------------------------------------------
6+
systimer_ticks dq 0
7+
tasktimer_ticks dq 0
8+
keyboard_scancode dq 0
9+
error_code_low dw 0
10+
error_code_high dw 0
11+
12+
int_message dw 17
13+
db 'Interrupt raised!'
14+
15+
division_by_zero_message dw 17
16+
db 'Division by zero!'
17+
18+
invalid_opcode_message dw 15
19+
db 'Invalid Opcode!'
20+
21+
gpf_message dw 25
22+
db 'General Protection Fault!'
23+
24+
pf_message dw 11
25+
db 'Page Fault!'
26+
27+
alignment_check_message dw 26
28+
db 'Alignment Check Exception!'
29+
30+
;---Code------------------------------------------------------------------------
31+
ISR_dummy:
32+
;***************************************************************************;
33+
; Just a dummy generic handler. It prints the message "Interrupt raised!". ;
34+
;***************************************************************************;
35+
cli
36+
push rax
37+
push r8
38+
push r9
39+
push rsi
40+
mov ah, (VGA_COLOR_RED << 4) | VGA_COLOR_LIGHT_BROWN
41+
mov r8, 1
42+
mov r9, 1
43+
mov rsi, int_message
44+
Call Print
45+
pop rsi
46+
pop r9
47+
pop r8
48+
pop rax
49+
.halt: hlt
50+
jmp .halt ; Infinite loop
51+
iretq
52+
53+
54+
ISR_Division_by_Zero:
55+
;***************************************************************************;
56+
; Divizion by zero handler ;
57+
;***************************************************************************;
58+
cli
59+
push rax
60+
push r8
61+
push r9
62+
push rsi
63+
mov ah, (VGA_COLOR_RED << 4) | VGA_COLOR_LIGHT_BROWN
64+
mov r8, 1
65+
mov r9, 1
66+
mov rsi, division_by_zero_message
67+
Call Print
68+
pop rsi
69+
pop r9
70+
pop r8
71+
pop rax
72+
.halt: hlt
73+
jmp .halt ; Infinite loop
74+
iretq
75+
76+
77+
ISR_Invalid_Opcode:
78+
;***************************************************************************;
79+
; Invalid Opcode handler ;
80+
;***************************************************************************;
81+
cli
82+
push rax
83+
push r8
84+
push r9
85+
push rsi
86+
mov ah, (VGA_COLOR_RED << 4) | VGA_COLOR_LIGHT_BROWN
87+
mov r8, 1
88+
mov r9, 1
89+
mov rsi, invalid_opcode_message
90+
Call Print
91+
pop rsi
92+
pop r9
93+
pop r8
94+
pop rax
95+
.halt: hlt
96+
jmp .halt ; Infinite loop
97+
iretq
98+
99+
100+
ISR_GPF:
101+
;***************************************************************************;
102+
; General Protection Fault handler ;
103+
;***************************************************************************;
104+
cli
105+
push rax
106+
push r8
107+
push r9
108+
push rsi
109+
mov ah, (VGA_COLOR_RED << 4) | VGA_COLOR_LIGHT_BROWN
110+
mov r8, 1
111+
mov r9, 1
112+
mov rsi, gpf_message
113+
Call Print
114+
pop rsi
115+
pop r9
116+
pop r8
117+
pop rax
118+
.halt: hlt
119+
jmp .halt ; Infinite loop
120+
iretq
121+
122+
123+
ISR_Page_Fault:
124+
;***************************************************************************;
125+
; Page Fault handler ;
126+
;***************************************************************************;
127+
cli
128+
pop word [error_code_high]
129+
pop word [error_code_low]
130+
push rax
131+
push r8
132+
push r9
133+
push rsi
134+
mov ah, (VGA_COLOR_RED << 4) | VGA_COLOR_LIGHT_BROWN
135+
mov r8, 1
136+
mov r9, 1
137+
mov rsi, pf_message
138+
call Print
139+
pop rsi
140+
pop r9
141+
pop r8
142+
pop rax
143+
.halt: hlt
144+
jmp .halt ; Infinite loop
145+
iretq
146+
147+
148+
ISR_Alignment_Check:
149+
;***************************************************************************;
150+
; Alignment Check Exception handler ;
151+
;***************************************************************************;
152+
cli
153+
push rax
154+
push r8
155+
push r9
156+
push rsi
157+
mov ah, (VGA_COLOR_RED << 4) | VGA_COLOR_LIGHT_BROWN
158+
mov r8, 1
159+
mov r9, 1
160+
mov rsi, alignment_check_message
161+
Call Print
162+
pop rsi
163+
pop r9
164+
pop r8
165+
pop rax
166+
.halt: hlt
167+
jmp .halt ; Infinite loop
168+
iretq
169+
170+
171+
ISR_systimer:
172+
;*****************************************************************************;
173+
; System Timer Interrupt Service Routine (IRQ0 mapped to INT 0x20) ;
174+
;*****************************************************************************;
175+
push rax
176+
mov al, PIC_EOI ; Send EOI (End of Interrupt) command
177+
out PIC1_COMMAND, al
178+
pop rax
179+
inc qword [systimer_ticks]
180+
inc qword [tasktimer_ticks]
181+
cmp qword [tasktimer_ticks], 1 ; Every how many ticks we want to switch tasks.
182+
jg .switch_task
183+
iretq
184+
185+
.switch_task:
186+
; set tasktimer_ticks to 0
187+
mov qword [tasktimer_ticks], 0
188+
; In long mode, when an interrupt occurs, the processor pushes in the stack
189+
; the interrupted program's stack pointer (SS:RSP), the RFLAGS, and the
190+
; return pointer (CS:RIP). In order to switch task, we have to replace them.
191+
; Therefore, we remove (pop) them from the stack.
192+
pop qword [return_address] ; RIP
193+
pop qword [code_segment] ; CS
194+
pop qword [rflags] ; RFLAGS
195+
pop qword [stack_pointer] ; RSP
196+
pop qword [stack_segment] ; SS
197+
; We save the current task state in the active task slot.
198+
call Save_task_state
199+
; We activate the next task slot
200+
inc qword [active_task_slot]
201+
; We check if the current task was the last task.
202+
push rax
203+
mov rax, [num_tasks]
204+
cmp [active_task_slot], rax
205+
pop rax
206+
jnz .load
207+
; If we reach the last task, switch to the first task
208+
mov qword [active_task_slot], 0
209+
.load:
210+
; Load the next task state from the active task slot.
211+
call Load_task_state
212+
; We now push back to the stack the values we have loaded for the next task.
213+
push qword [stack_segment]
214+
push qword [stack_pointer]
215+
push qword [rflags]
216+
push qword [code_segment]
217+
push qword [return_address]
218+
; The instruction IRETQ will load these values to the proper registers
219+
; and we will switch to the next task.
220+
iretq
221+
222+
223+
ISR_keyboard:
224+
;*****************************************************************************;
225+
; Keyboard Controller Interrupt Service Routine (IRQ1 mapped to INT 0x21) ;
226+
;*****************************************************************************;
227+
push rax
228+
xor rax, rax
229+
in al, 0x60 ; MUST read byte from keyboard (else no more interrupts).
230+
mov [keyboard_scancode], al
231+
mov al, PIC_EOI ; Send EOI (End of Interrupt) command
232+
out PIC1_COMMAND, al
233+
pop rax
234+
iretq

0 commit comments

Comments
 (0)