Recently I'm trying to get a hang on how bootloaders work. I'm writing my loader in nasm assembler and test it with bochs and a floppy image.
The compiled binaries for stage 1 and 2 get joined via copy into one image. This image is exactly as I want it. 512Bytes stage1 code (magicnumber included and it loads just fine) and 512 stage2 code in the 2nd sector.
But I think my problem is loading the sector into the ram 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's 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 googled thoroughly and found nothing describing exactly how to load a sector into the ram and jump into it. Not even the Magicnumber of the 2nd sector is found by my programm.
Would be great if it is just some miscalculation on the addresses.
Update: Current sourcecode, the line where it has a lockup is marked. I set all 4 main registers to 0 out of pure paranoia.
Update2: Again the current version. No stuff done between setting up the registers and issuing int 13h.