Skip to content

Commit 7af6d3e

Browse files
committed
Automatic commit Thu Apr 21 05:00:40 PM EEST 2022
1 parent 68808d5 commit 7af6d3e

File tree

16 files changed

+1064
-2
lines changed

16 files changed

+1064
-2
lines changed

os/part1/stage1/disk.asm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,5 @@ Real_mode_read_disk:
6868
.print_error:
6969
mov si, disk_error_message
7070
call Real_mode_println
71-
.halt: hlt
72-
jmp .halt; Infinite loop. We cannot recover from disk error.
71+
.halt: hlt
72+
jmp .halt; Infinite loop. We cannot recover from disk error.

os/part3/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/part3/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_dummy , 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_dummy , 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, 0x8F ;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/part3/kernel/isr.asm

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
; INTERRUPT SERVICE ROUTINES
2+
3+
BITS 64
4+
5+
;---Initialized data----------------------------------------------------------
6+
systimer_ticks dq 0
7+
keyboard_scancode dq 0
8+
error_code_low dw 0
9+
error_code_high dw 0
10+
11+
int_message dw 17
12+
db 'Interrupt raised!'
13+
14+
division_by_zero_message dw 17
15+
db 'Division by zero!'
16+
17+
gpf_message dw 25
18+
db 'General Protection Fault!'
19+
20+
pf_message dw 11
21+
db 'Page Fault!'
22+
23+
24+
;---Code------------------------------------------------------------------------
25+
ISR_dummy:
26+
;***************************************************************************;
27+
; Just a dummy generic handler. It prints the message "Interrupt raised!". ;
28+
;***************************************************************************;
29+
cli
30+
push rax
31+
push r8
32+
push r9
33+
push rsi
34+
mov ah, (VGA_COLOR_RED << 4) | VGA_COLOR_LIGHT_BROWN
35+
mov r8, 1
36+
mov r9, 1
37+
mov rsi, int_message
38+
Call Print
39+
pop rsi
40+
pop r9
41+
pop r8
42+
pop rax
43+
.halt: hlt
44+
jmp .halt ; Infinite loop
45+
iretq
46+
47+
48+
ISR_Division_by_Zero:
49+
;***************************************************************************;
50+
; Divizion by zero handler ;
51+
;***************************************************************************;
52+
cli
53+
push rax
54+
push r8
55+
push r9
56+
push rsi
57+
mov ah, (VGA_COLOR_RED << 4) | VGA_COLOR_LIGHT_BROWN
58+
mov r8, 1
59+
mov r9, 1
60+
mov rsi, division_by_zero_message
61+
Call Print
62+
pop rsi
63+
pop r9
64+
pop r8
65+
pop rax
66+
.halt: hlt
67+
jmp .halt ; Infinite loop
68+
iretq
69+
70+
71+
ISR_GPF:
72+
;***************************************************************************;
73+
; General Protection Fault handler ;
74+
;***************************************************************************;
75+
cli
76+
push rax
77+
push r8
78+
push r9
79+
push rsi
80+
mov ah, (VGA_COLOR_RED << 4) | VGA_COLOR_LIGHT_BROWN
81+
mov r8, 1
82+
mov r9, 1
83+
mov rsi, gpf_message
84+
Call Print
85+
pop rsi
86+
pop r9
87+
pop r8
88+
pop rax
89+
.halt: hlt
90+
jmp .halt ; Infinite loop
91+
iretq
92+
93+
94+
ISR_Page_Fault:
95+
;***************************************************************************;
96+
; Page Fault handler ;
97+
;***************************************************************************;
98+
cli
99+
pop word [error_code_high]
100+
pop word [error_code_low]
101+
push rax
102+
push r8
103+
push r9
104+
push rsi
105+
mov ah, (VGA_COLOR_RED << 4) | VGA_COLOR_LIGHT_BROWN
106+
mov r8, 1
107+
mov r9, 1
108+
mov rsi, pf_message
109+
call Print
110+
pop rsi
111+
pop r9
112+
pop r8
113+
pop rax
114+
.halt: hlt
115+
jmp .halt ; Infinite loop
116+
iretq
117+
118+
119+
ISR_systimer:
120+
;*****************************************************************************;
121+
; System Timer Interrupt Service Routine (IRQ0 mapped to INT 0x20) ;
122+
;*****************************************************************************;
123+
push rax
124+
inc qword [systimer_ticks]
125+
mov al, PIC_EOI ; Send EOI (End of Interrupt) command
126+
out PIC1_COMMAND, al
127+
pop rax
128+
iretq
129+
130+
131+
ISR_keyboard:
132+
;*****************************************************************************;
133+
; Keyboard Controller Interrupt Service Routine (IRQ1 mapped to INT 0x21) ;
134+
;*****************************************************************************;
135+
push rax
136+
xor rax, rax
137+
in al, 0x60 ; MUST read byte from keyboard (else no more interrupts).
138+
mov [keyboard_scancode], al
139+
mov al, PIC_EOI ; Send EOI (End of Interrupt) command
140+
out PIC1_COMMAND, al
141+
pop rax
142+
iretq

os/part3/kernel/kernel.asm

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
BITS 64 ; We have entered the long mode! :)
2+
3+
;---Define----------------------------------------------------------------------
4+
%define DATA_SEG 0x0010
5+
6+
;---Initialized data------------------------------------------------------------
7+
hello_world_message dw 12
8+
db 'Hello World!'
9+
10+
ticks_message dw 19
11+
db 'System timer ticks:'
12+
13+
scancode_message dw 19
14+
db 'Keyboard scan code:'
15+
16+
;---Include---------------------------------------------------------------------
17+
%include "kernel/idt.asm"
18+
%include "kernel/isr.asm"
19+
%include "kernel/video.asm"
20+
21+
;---Code------------------------------------------------------------------------
22+
Kernel:
23+
lidt [IDTR] ; Load our IDTR
24+
25+
mov al, 0x80 ; OCW1: Unmask all interrupts at master PIC
26+
out PIC1_DATA, al
27+
mov al, 0x80 ; OCW1: Unmask all interrupts at master PIC
28+
out PIC2_DATA, al
29+
30+
; Set all segments registers to DATA_SEG
31+
mov ax, DATA_SEG
32+
mov ds, ax
33+
mov es, ax
34+
mov fs, ax
35+
mov gs, ax
36+
mov ss, ax
37+
38+
; Clear the screen.
39+
mov rax, 0x0020002000200020 ; Set background color to black (0) and
40+
; character to blank space (20).
41+
call Fill_screen
42+
43+
; Print "Hello World!" at the upper right corner
44+
mov ah, 0x1E
45+
mov r8, 69
46+
mov r9, 1
47+
mov rsi, hello_world_message
48+
call Print
49+
50+
; Uncomment the following lines if you want to test the "Division by zero" exception.
51+
; mov eax, 1
52+
; mov ecx, 0
53+
; div ecx
54+
55+
.loop:
56+
; Print system timer ticks.
57+
mov ah, VGA_COLOR_LIGHT_GREEN
58+
mov r8, 1
59+
mov r9, 2
60+
mov rsi, ticks_message
61+
Call Print
62+
mov r8, 21
63+
mov r9, 2
64+
mov r10, [systimer_ticks]
65+
call Print_hex
66+
; Print keyboard scan code.
67+
mov ah, VGA_COLOR_LIGHT_CYAN
68+
mov r8, 1
69+
mov r9, 4
70+
mov rsi, scancode_message
71+
Call Print
72+
mov r8, 21
73+
mov r9, 4
74+
mov r10, [keyboard_scancode]
75+
call Print_hex
76+
jmp .loop ; Infinite loop.

0 commit comments

Comments
 (0)