bits 16 ; boot sectors run in real mode org 7C00h ; BIOS loads us at 0x7c00 KERNEL_OFFSET equ 1000h ; where we will load our kernel mov [BOOT_DRIVE], dl ; BIOS puts the number of our boot drive in dl, so we will want to remember this mov bp, 9000h ; initialize stack at a spot sufficiently distanced from this code mov sp, bp mov di, 0 xor ax, ax ; clear accumulator int 13h ; BIOS disk services, with a cleared accumulator this will reset the disk controller jc reset_error ; halt if controller reset fails mov ah, 2 ; instruct BIOS's interrupt 13h to read sectors mov al, 10 ; load 10 sectors, might be excessive (for now) but it's still good to do so xor ch, ch ; read from 1st cylinder mov cl, 2 ; start reading from 2nd sector, right after the boot sector xor dh, dh ; read from 1st head xor bx, bx ; clear B register mov es, bx ; clear extended segment mov bx, KERNEL_OFFSET ; put the sectors in our desired offset ; dl holds the number of the drive to read from, but BIOS already filled this in int 13h ; do the read jc read_error ; halt if read fails cmp al, 10 ; make sure we actually read 10 sectors jl read_error ; halt if we didn't jmp switch_to_pm ; if all is good, begin the switch to 32-bit protected mode reset_error mov bx, 0B800h mov es, bx mov byte [es:di], '1' jmp halt read_error mov bx, 0B800h mov es, bx mov byte [es:di], '2' jmp halt halt jmp $ %include "a20.s" %include "protected.s" BOOT_DRIVE db 0 ; reserve a spot in RAM for our boot drive variable times 510-($-$$) db 0 dw 0AA55h ; MBR signature