Code: Select all
global lngmd_start
extern kernel_main
extern gdt.data
section .text
bits 64
lngmd_start:
mov ax, gdt.data
mov ss, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
;cli
call map_entries
lidt [idt.pointer]
sti
;call kernel_main
;int 0x00
jmp krnl_hlt
map_entries:
mov rbx, idt
.map_exceptions:
mov rdx, 0
mov r8, exception_handler
mov rcx, 32
jmp .loop
.map_irqs_pic1:
mov rdx, 1
mov r8, isr_handler.pic1
mov rcx, 8
jmp .loop
.map_irqs_pic2:
mov rdx, 2
mov r8, isr_handler.pic2
mov rcx, 8
.loop:
mov rax, r8
mov word [rbx], ax
shr rax, 16
mov word [rbx + 6], ax
shr rax, 16
mov dword [rbx + 8], eax
add rbx, 16
dec rcx
;jmp krnl_hlt ;This statement would behave as intended and halt the kernel, printing "a2"
jne .loop
jmp krnl_hlt ; This statement causes INVALID_OPCODE, instead of printing "a2" then halting. Removing this statement causes the kernel to simply hang without any output
test rdx, rdx
je .map_irqs_pic1
dec rdx
test rdx, rdx
je .map_irqs_pic2
ret
idt:
.exception_0:
dw 0
dw 0x8
db 0
db 10001110b
dw 0
dd 0
dd 0
; --------------------------------
; exceptions 1 - 30
; --------------------------------
.exception_31:
dw 0
dw 0x8
db 0
db 10001110b
dw 0
dd 0
dd 0
.irq_0:
dw 0
dw 0x8
db 0
db 10001110b
dw 0
dd 0
dd 0
; --------------------------------
; irqs 1 - 14
; --------------------------------
.irq_15:
dw 0
dw 0x8
db 0
db 10001110b
dw 0
dd 0
dd 0
.pointer:
dw $ - idt - 1
dq idt
exception_handler:
jmp krnl_hlt
isr_handler:
.pic1:
mov ax, 0x20
out 0x20, ax
iretq
.pic2:
mov ax, 0x20
out 0xa0, ax
iretq
krnl_hlt:
mov dword [0xb8000], 0x0c320c61
abbc:
hlt
nop
jmp abbc