; KBOOT - Kern Bootloader ; Most of the code is taken from Limine (https://github.com/limine-bootloader/limine) ; I tried to add more documentation than the Limine code had, but it's not everything ; Any of my code is pretty bad, so i recommend using an existing bootloader [org 0x7c00] [bits 16] start: jmp .bpb_end ; Some BIOSes will override the FAT BPB area, ; so we just fill it out to avoid pottentially ; overriding bootloader code. ; Source: https://github.com/limine-bootloader/limine/blob/trunk/stage1/hdd/bootsect.asm .bpb: times 3-($-$$) db 0 .bpb_oem_id: db "KBOOT " .bpb_sector_size dw 512 .bpb_sects_per_clust: db 0 .bpb_reserved_sects: dw 0 .bpb_fat_count: db 0 .bpb_root_dir_entries: dw 0 .bpb_sector_count: dw 0 .bpb_media_type: db 0 .bpb_sects_per_fat: dw 0 .bpb_sects_per_track: dw 18 .bpb_heads_count: dw 2 .bpb_hidden_sects: dd 0 .bpb_sect_count_big: dd 0 .bpb_drive_num: db 0 .bpb_reserved: db 0 .bpb_signature: db 0 .bpb_volume_id: dd 0 .bpb_volume_label: db "KBOOT " .bpb_filesystem_type: times 8 db 0 .bpb_end: cli cld jmp 0x0000:.init_codeseg ; Long jump to set CS = 0 ; Zero out segment regs (Because segmentation is shit) .init_codeseg: xor si, si ; We cannot change segment regs directly mov ds, si ; Data Segment mov es, si ; Extra Segment mov ss, si ; Stack Segment mov sp, 0x7c00 ; Set Stack Pointer sti ; We probably won't be booting from a floppy, so ; ignore if boot drive is < 0x80 and assume an error cmp dl, 0x80 jl err.0 ; Also anything above 0x8f is "dubious" so we also ; just assume an error cmp dl, 0x8f jg err.1 ; Check that int 13h extensions are supported .int13chk: mov ah, 0x41 mov bx, 0x55aa ; Expects bx to be this magic value int 0x13 ; Will se CF if unsupported jc err.2 cmp bx, 0xaa55 ; Also sets bx to this magic jne err.3 ; Load the stage 2 bootloader code to 0x70000 .load_stage2: push 0x7000 pop es ; ES = 0x7000 xor bx, bx ; ES:BX = 0x70000 mov eax, 512 xor ebp, ebp mov ecx, 512 call read_sectors jc err.4 ; CF was set -> failed to read from disk .enable_protected: ; Load GDT Pointer lgdt [gdtp] ; Set PE (Protected mode Enable) flag cli mov eax, cr0 or eax, 1 ; Bit 1 - PE mov cr0, eax ; Far jump to protected mode jmp code_seg:vector %include "boot/disk.s" ; Disk I/O helper functions %include "boot/gdt.s" ; Global Descriptor Table ; Handles an error err: ; Error codes .4: inc si ; Failed to read stage2 from disk .3: inc si ; Int 13h extensions unsupported (BX wasn't magic) .2: inc si ; Int 13h extensions unsupported (CF was set) .1: inc si ; Invalid boot drive number (> 0x8f) .0: ; Invalid boot drive number (< 0x80) ; Common error handler add si, '0' | (0x4f << 8) ; Store error code number char in SI, white on red push 0xb800 ; VGA Text mode video memory pop es ; ES = 0xb800 mov word [es:0], si ; Write character ; Hang sti .h: hlt jmp .h [bits 32] ; Protected mode entry vector vector: mov eax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax and edx, 0xff ; Call stage 2 bootloader call 0x70000 ; Padding and boot signature times 510-($-$$) db 0 dw 0xaa55