[org 0x7C00] _start: xor ax, ax mov ds, ax mov es, ax mov ss, ax mov fs, ax mov gs, ax cli ;; Disable all interrupts cld ;; Strings shall increment mov [boot_drive], dl ;; Save the boot drive mov si, boot_sig call print_str call enable_a20 call disk_load ;; Enable protected mode mov eax, cr0 or al, 1 mov cr0, eax lgdt [GDTR] jmp 0x8:0x8000 GDT32: .null_desc: dw 0x0000 dw 0x0000 db 0x00 db 0b00000000 db 0b00000000 db 0x00 .code_desc: dw 0xFFFF dw 0x0000 db 0x00 db 0b10011010 db 0b11001111 db 0x00 .data_desc: dw 0xFFFF dw 0x0000 db 0x00 db 0b10010010 db 0b11001111 db 0x00 GDTR: dw $ - GDT32 - 1 dd GDT32 ;; ;; Write a string to the screen ;; ;; [SI]: Base address of string ;; print_str: lodsb ;; Load *(SI++) -> AL or al, al ;; Null byte? jz .done ;; Yup, finish mov ah, 0x0E ;; Print char int 0x10 ;; BIOS call jmp print_str ;; Loop again until NUL .done: ret ;; ;; Enable the A20 gate to access the full ;; 16 megs ;; enable_a20: in al, 0x92 ;; Check the state test al, 2 ;; is it already set? jnz .done ;; Yes, no need to re-enable or al, 2 ;; No, enable it out 0x92, al ;; Write the new value back .done: ret DAP: .size: db 0x10 .reserved: db 0x00 .count: dw 1 .buffer: dw 0x8000 .segment: dw 0 .lba_lo: dd 1 .lba_hi: dd 0 disk_load: mov si, DAP mov ah, 0x42 mov dl, [boot_drive] int 0x13 jc .disk_err ret .disk_err: mov si, disk_errmsg call print_str .hang: hlt jmp .hang boot_sig: db "* beepboot stage0", 0x0A, 0x0D, 0x00 disk_errmsg: db "[!] failed to read disk", 0x0A, 0x0D, 0x00 boot_drive: db 0 times 510 - ($ - $$) db 0 dw 0xAA55