Recently, I am trying to understand how bootloaders work. I write my bootloader in nasm assembler and test it with bochs and a floppy image.
Compiled binaries for steps 1 and 2 are combined by copying to a single image. This image is exactly the way I want. 512Bytes stage1 code (magicnumber is enabled and it loads just fine) and 512 stage2 code in the second sector.
But I think that my problem is loading the sector into the plunger and jumping into it. Is there something wrong with my code?
Stage1.asm
BITS 16 start: mov ax, 07C0h ; Set up 4K stack space after this bootloader add ax, 288 ; (4096 + 512) / 16 bytes per paragraph mov ss, ax mov sp, 4096 mov ax, 07C0h ;Set data segment to where we're loaded mov ds, ax mov si,s_version call print_string ; ## Load stage2 mov si,s_loading call print_string xor ax,ax xor bx,bx xor cx,cx xor dx,dx ;read 2nd sector mov ah,02h mov al,1 ;read 1 mov ch,0 ;on track 0 mov cl,2 ;2nd sector mov dh,0 ;head 1 mov dl,0 ;from floppy a mov bx,09C0h;destination segment mov es,bx mov bx,0 ;destination offset int 13h ;<-- Fails right here mov si,s_sector call print_string ;print number of read sectors add ax, 48 mov ah, 0Eh int 10h mov al, 21 mov ah, 0Eh int 10h ;print the sector magicnumber (debugging purposes) mov al, [09C0h+511] int 10h xor ax,ax int 16h mov si,s_jumping call print_string call word 09C0h:0000h ; #### print a string from si print_string: push ax push bx mov ah, 0Eh .repeat: lodsb cmp al, 0 je .exit int 10h jmp .repeat .exit: pop bx pop ax ret ; **** ; #### define strings s_version db 'VeOS 0.0.0.1',10,13,0 s_loading db 'Loading Stage2...',10,13,0 s_sector db 'Loading sector...',10,13,0 s_jumping db 'Passing control to Stage2.',10,13,0 ; **** ;fillup with zeros times 510-($-$$) db 0 ;boot signature dw 0xAA55
stage2.asm
BITS 16 start: mov ax, 09C0h ; Set up 4K stack space after this bootloader add ax, 288 ; (4096 + 512) / 16 bytes per paragraph mov ss, ax mov sp, 4096 mov ax, 09C0h ;Set data segment to where we're loaded mov ds, ax mov ah, 0Eh mov al, 21 ;"!" int 10h mov ah, 00h int 16h jmp $ times 511-($-$$) db 0 ;Magicnumber for debugging db 0x41
I carefully sorted into Google and did not find anything that accurately describes how to load a sector into a plunger and jump into it. My program is also not listed in Magicnumber of the 2nd sector.
It would be great if it was just a miscalculation of addresses.
Update: The current source code, the line in which it has a lock, is marked. I set all 4 main registers to 0 from pure paranoia.
Update2: Again the current version. Nothing happens between setting registers and issuing int 13h.