Another bootloader problem
Posted: Fri Jan 30, 2015 5:27 pm
Recently i used int 13h function 2 to load my kernel. I passed the bootdrive, start sector 2, destination buffer 0000:0800 and my kernel has been loaded.
Since my kernel gets bigger and the bios can only load up to 63 (~31KiB) sectors at once, I considered the following function:
But the problem is that it does not work
I've debugged a lot using Bochs. It seems that the first sectors are loaded properly and the second stage loader is executed. But at some point the CPU runs into invalid code. (My kernel is definitely working with the mentioned method above).
For those who want to know: The stack is set up correctly (0000:7C00) and the start sector passed to int 13h/2 is counted from 1.
My kernel image without the 512-byte bootloader is 28KiB in size and inserted into Bochs as a 1.44M floppy.
An interesting point is that in the Bochs-Logfile it say 44 times 'read() on floppy image returns 0', so only 36 sectors, 18KiB get loaded from the file into memory.
Since my kernel gets bigger and the bios can only load up to 63 (~31KiB) sectors at once, I considered the following function:
Code: Select all
mov ax, 0x0000
mov es, ax
mov bx, 0x8000
mov ax, 1
mov cl, 80 ;load 80 sectors (40KiB)
call ReadSectors
jc .error
jmp 0x0000:0x8000
;...
;;es: buffer segment, bx: buffer offset, ax: start sector, cl: num sectors
ReadSectors:
mov byte[.remainsec], cl
push ax
push bx
push es
mov ah, 8 ;get sectors per track
mov dl,[bootdrive]
int 13h
and cl, 0x3F
pop es
pop bx
pop ax
mov byte[.secpertrack], cl
div cl
mov byte[.currcylinder], al ;startcylinder = absolute sector/sectors per track
mov byte[.currsector], ah ;startsector = absolute sector % sectors per track
.readsectors:
mov al, 1 ;;read one sector
mov ch, byte[.currcylinder] ;cylinder
mov cl, byte[.currsector] ;sector
inc cl ;sector count starts at 1
mov dh, 0 ;head = 0
mov ah, 2 ;function "read"
mov dl,[bootdrive]
int 0x13
jnc .success
stc
ret ;;failure
.success:
inc byte[.currsector] ;inc sector
mov al, byte[.secpertrack]
cmp byte[.currsector], al
jb .nowrap ;if greater than sectors per track, increment track and set sector to 0
mov byte[.currsector], 0
inc byte[.currcylinder]
.nowrap:
dec byte[.remainsec] ;decrement sector count
jz .end
mov ax, es ;add 512 to buffer pointer
add ax, 0x20 ;512 >> 4
mov es, ax
jmp .readsectors
.end:
clc
ret
.secpertrack db 0
.currsector db 0
.currcylinder db 0
.remainsec db 0
I've debugged a lot using Bochs. It seems that the first sectors are loaded properly and the second stage loader is executed. But at some point the CPU runs into invalid code. (My kernel is definitely working with the mentioned method above).
For those who want to know: The stack is set up correctly (0000:7C00) and the start sector passed to int 13h/2 is counted from 1.
My kernel image without the 512-byte bootloader is 28KiB in size and inserted into Bochs as a 1.44M floppy.
An interesting point is that in the Bochs-Logfile it say 44 times 'read() on floppy image returns 0', so only 36 sectors, 18KiB get loaded from the file into memory.