Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Hey guys. So I've been trying to write a small-ish bootloader which can load a kernel. But I cannot seem to do that... INT 13h gives me no errors (at least I think so - carry flag is 0), but nothing happens when i try to run that kernel code. I am not sure if it is my code's problem or floppy disk having a wrong format. Here is my assembly code (fasm):
mov ax, 7c0h
mov ds, ax
mov ah, 02h ; read sector(s) into the memory
mov al, 01h ; number of sectors to read
mov ch, 00h ; cylinder (track) number
mov cl, 01h ; sector number (1 is the first one)
mov dh, 00h ; head number
mov dl, 00h ; floppy disk
mov bx, kernel
int 13h
jc error
jmp kernel
jmp error ; No idea how may this ever run
error:
mov si, error_msg
.next:
lodsb
cmp al, 00h
je .f_end
mov ah, 0Eh
mov bh, 00h
mov bl, 0fh
int 10h
jmp .next
.f_end:
jmp $
error_msg db 'Error!', 00h
nulls: times 510-($-$$) db 00h
boot_signature dw 0xAA55 ; Boot sector signature
kernel:
mov ah, 0Eh
mov al, 35h
int 10h
mov ah, 00h
int 16h
I've put some code after label kernel so it'd get loaded into the floppy file (it works). I create the floppy file using:
Roman wrote:What emulator are you using? If it's QEMU, you can use memsave <addr> <size> <file> to dump the memory, where you expect the kernel to be loaded.
Edit: what about the 'org' and the ES, you didn't set?
I've moved value into the ds register before, but it seems like a bad idea. For some reason when I placed 'org 7c00h' it actually worked. Thanks dude! But what about the ES register? What should I put into it?
iansjack wrote:You load just the first sector from the disk (which the BIOS has already read); the kernel code is contained in the second sector.
Indeed. For some reason I thought that sector 1 is going to be the one right after the bootloader. Thanks!
Roman wrote:What emulator are you using? If it's QEMU, you can use memsave <addr> <size> <file> to dump the memory, where you expect the kernel to be loaded.
Edit: what about the 'org' and the ES, you didn't set?
I've moved value into the ds register before, but it seems like a bad idea. For some reason when I placed 'org 7c00h' it actually worked. Thanks dude! But what about the ES register? What should I put into it?
The buffer, where BIOS places the sectors, is at ES:BX. The org statement tells the assembler, where the code is loaded. You can set org to 0x7C00 and segments to 0. The assembler will compute label pointers with this formula: org + offset in the file. The CPU does it by multiplying a segment by 0x10 and adding the pointer. You can read more here.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay