add kernel stuff, idt, welcome message
This commit is contained in:
108
asm/boot.asm
108
asm/boot.asm
@@ -12,6 +12,13 @@ KERNEL_LOAD_ADDR_ES equ 0x1000 ; kernel to be loaded at es * 0x10 + 0x0000
|
||||
PAGE_TABLE_LOAD_ADDR equ 0x1000 ; start of page table; 4 * pt size
|
||||
PAGE_TABLE_SIZE equ 0x1000 ; size of page table in bytes
|
||||
|
||||
; 64 bit IDT stuff
|
||||
IDT_ADDR equ 0x8000 ; bottom of IDT
|
||||
IDT_SIZE equ 0x1000 ; size of IDT
|
||||
|
||||
IDT_SEGMENT equ 0x0008 ; gdt code segment to jump to for idt calls
|
||||
|
||||
; magic numbers and things
|
||||
A20_LINE_ENABLE equ 0x2401 ; magic number in ax to enable a20 line with 0x15
|
||||
BIOS_INT_DISK_OP equ 0x13
|
||||
BIOS_INT_MEMORY_OP equ 0x15
|
||||
@@ -42,7 +49,7 @@ cld
|
||||
; activate a20
|
||||
mov ax, A20_LINE_ENABLE
|
||||
int BIOS_INT_MEMORY_OP
|
||||
jc error_a20_line
|
||||
jc error
|
||||
mov si, msg_a20_line
|
||||
call print
|
||||
|
||||
@@ -59,7 +66,7 @@ xor bx, bx
|
||||
; read disk
|
||||
mov ah, 0x02
|
||||
int BIOS_INT_DISK_OP
|
||||
jc error_disk_read
|
||||
jc error
|
||||
mov si, msg_disk_read
|
||||
call print
|
||||
|
||||
@@ -143,17 +150,11 @@ lm_load:
|
||||
|
||||
jmp 0x08:lm_start
|
||||
|
||||
error_a20_line:
|
||||
error:
|
||||
mov si, .msg
|
||||
call print
|
||||
jmp done
|
||||
.msg db "err a20 line", 0x00
|
||||
|
||||
error_disk_read:
|
||||
mov si, .msg
|
||||
call print
|
||||
jmp done
|
||||
.msg db "err disk read", 0x00
|
||||
.msg db "err ", 0x00
|
||||
ret
|
||||
|
||||
done:
|
||||
hlt
|
||||
@@ -172,11 +173,6 @@ print:
|
||||
popad
|
||||
ret
|
||||
|
||||
; TODO make real idt
|
||||
empty_idt:
|
||||
dw 0 ; length
|
||||
dd 0 ; base
|
||||
|
||||
; TODO make readable (yoinked from https://wiki.osdev.org/Entering_Long_Mode_Directly)
|
||||
gdt_data:
|
||||
dq 0x0000000000000000
|
||||
@@ -201,11 +197,89 @@ lm_start:
|
||||
; set up serial device
|
||||
; TODO poll and whatnot (in rust??)
|
||||
mov dx, 0x3F8
|
||||
|
||||
; qemu -no-graphic overlaps serial and bios output without this
|
||||
mov al, 0x0D
|
||||
out dx, al
|
||||
mov al, 0x0A
|
||||
out dx, al
|
||||
|
||||
; initialize IDT at IDT_ADDR
|
||||
call idt_init
|
||||
|
||||
int3 ; silly test
|
||||
|
||||
jmp KERNEL_LOAD_ADDR_ES * 0x10
|
||||
|
||||
idt_init:
|
||||
; clear space for idt
|
||||
mov rdi, IDT_ADDR
|
||||
push di
|
||||
mov rcx, IDT_SIZE / 4
|
||||
xor rax, rax
|
||||
cld
|
||||
rep stosd ; clear double word for each rcx
|
||||
pop di
|
||||
|
||||
push rdx ; dx contains the output device
|
||||
; nothing between here and the `pop rdx` will be able to print
|
||||
|
||||
; breakpoint
|
||||
mov rdi, 0x8E ; present, no dpl, interrupt
|
||||
mov rsi, 0x03 ; breakpoint interrupt
|
||||
lea rdx, [int_hdl_dummy]
|
||||
call mk_idt_entry
|
||||
|
||||
pop rdx ; get back dx output device
|
||||
|
||||
lidt [idt_descriptor]
|
||||
|
||||
ret
|
||||
|
||||
int_hdl_dummy:
|
||||
mov rsi, .msg
|
||||
call lm_print
|
||||
iretq
|
||||
.msg db "INTdummy", 0x0D, 0x0A, 0x00
|
||||
|
||||
; rdi = flags
|
||||
; rsi = entry number
|
||||
; rdx -> handler
|
||||
mk_idt_entry:
|
||||
mov rax, rdx
|
||||
mov rcx, rsi
|
||||
|
||||
shl rcx, 4 ; offset = entry number * 16
|
||||
add rcx, IDT_ADDR
|
||||
|
||||
mov word [rcx + 0], ax ; offset
|
||||
mov word [rcx + 2], IDT_SEGMENT ; code segment
|
||||
mov word [rcx + 5], di
|
||||
mov byte [rcx + 4], 0 ; IST (0 = none)
|
||||
shr rax, 16
|
||||
mov word [rcx + 6], ax ; offset
|
||||
shr rax, 16
|
||||
mov dword [rcx + 8], eax ; offset
|
||||
mov dword [rcx + 12], 0 ; reserved
|
||||
ret
|
||||
|
||||
lm_print:
|
||||
.loop
|
||||
mov al, [rsi]
|
||||
test al, al
|
||||
jz .done
|
||||
out dx, al
|
||||
inc si
|
||||
jmp .loop
|
||||
.done:
|
||||
ret
|
||||
|
||||
idt_descriptor:
|
||||
dw IDT_SIZE - 1 ; size
|
||||
dq IDT_ADDR ; start
|
||||
|
||||
msg_a20_line db "a20 line", 0x0D, 0x0A, 0x00
|
||||
msg_disk_read db "disk read", 0x0D, 0x0A, 0x00
|
||||
msg_disk_read db "disk", 0x0D, 0x0A, 0x00
|
||||
|
||||
times 510-($-$$) db 0 ; 2 bytes less now
|
||||
db 0x55
|
||||
|
||||
Reference in New Issue
Block a user