ORG 0x0 BITS 16 _start: jmp short start nop ; Setup dummy BIOS Parameter block so a dumb BIOS does not corrupt us ; if it starts messing up with the parameter block times 33 db 0 start: ; Set CS to 0x07c0 with label step2 as its beginning offset jmp 0x07c0:step2 step2: ; Setup segments cli ; Disable interrupts mov ax, 0x07c0 mov ds, ax mov es, ax mov ax, 0x00 mov ss, ax mov sp, 0x7c00 ; Stack segment starts right before ds ; and grows down to 0x0. This works because ; Intel implements a full descending stack sti ; Enable interrupts mov si, load_msg call print ; Load sector from disk mov ah, 2 ; Read sector into memory mov al, 1 ; Read 1 sector mov ch, 0 ; Cylinder number mov cl, 2 ; Sector number to start reading from mov dh, 0 ; Head number ;DL ; Drive number (Already set by bios) ; Sector will be loaded at ES:BX. We already have ES set, ; just set the BX to an address after the end of the bootloader. This ; avoids the risk of corrupting any data from our bootloader. mov bx, kbuf_sector int 0x13 ; Jump if CF is set jc kload_failure ; On I/O error, CF is set ; Kernel loaded succesfully (hopefully) mov si, kbuf_sector call print jmp $ kload_failure: mov si, err_msg call print jmp $ print: mov bx, 0 .loop lodsb cmp al, 0 je .done call print_char jmp .loop .done: ret print_char: mov ah, 0x0e int 0x10 ret ; Static data load_msg: db 'Starting bootloader...', 0x0A, 0x0D, 0 divzero_msg: db 'Interrupts working properly...', 0x0A, 0x0D, 0 err_msg: db 'Failed to load kernel...', 0x0A, 0x0D, 0 ; Fill in to the end and add bootloader signature times 510 - ($ - $$) db 0 dw 0xAA55 ; This just labels an address after the bootloader. Just makes it easier ; to refer to the loaded sector from int 0x13. kbuf_sector: