global kboot global register_isr extern kmain extern timer_init ; Multiboot header section .mboothdr mboot_hdr: align 4 dd 0x1BADB002 dd 0x00 dd - (0x1BADB002 + 0x00) section .text kboot: cli call flush_gdt call flush_idt call timer_init call kmain cli hlt gdt: ; null descriptor dq 0 ; kernel code segment dw 0xFFFF ; limit (bits 0-15) dw 0x0000 ; base (bits 0-15) db 0x00 ; base (bits 16-23) db 0x9A ; access byte db 0xCF ; flags / limit (bits 16-19) db 0x00 ; base (bits 24-31) ; kernel data segment dw 0xFFFF dw 0x0000 db 0x00 db 0x92 db 0xCF db 0x00 ; userspace code segment dw 0xFFFF dw 0x0000 db 0x00 db 0xFA db 0xCF db 0x00 ; userspace data segment dw 0xFFFF dw 0x0000 db 0x00 db 0xF2 db 0xCF db 0x00 gdtp: dw ($-gdt-1) dd gdt flush_gdt: push ebp mov ebp, esp lgdt [gdtp] mov ax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax jmp 0x08:.end .end: pop ebp ret idt: times (256*8) db 0 idtp: dw ($-idt-1) dd idt int_handler: iret irq_handler: iret flush_idt: push ebp mov ebp, esp mov ecx, 0 mov edx, idt .loop: mov eax, int_handler cmp ecx, 0x20 jl .skip cmp ecx, 0x2f jg .skip mov eax, irq_handler .skip: mov [edx], ax mov word [edx+2], 0x08 mov byte [edx+4], 0 mov byte [edx+5], 0x8E shr eax, 16 mov [edx+6], ax add edx, 8 inc ecx cmp ecx, 256 je .end jmp .loop .end: lidt [idtp] call pic_init sti pop ebp ret ; void register_isr(uint8_t n, void *handler); register_isr: push ebp mov ebp, esp mov edx, [ebp+8] shl edx, 3 add edx, idt mov eax, [ebp+12] mov [edx], ax add edx, 6 shr eax, 16 mov [edx], ax pop ebp ret pic_init: push ebp mov ebp, esp mov al, 0x11 out 0x20, al out 0xA0, al mov al, 0x20 out 0x21, al out 0xA1, al mov al, 0x04 out 0x21, al mov al, 0x02 out 0xA1, al mov al, 0x01 out 0x21, al out 0xA1, al mov al, 0xFF out 0x21, al out 0xA1, al pop ebp ret