I wrote a bootloader and a kernel and want my bootloader to load my kernel
[org 0x7c00]
jmp start
;%include "console.inc"
start:
xor ax, ax
mov ds, ax
;call init_console
;call clrscr
;mov si, head
;mov ah, 0x0f
;call str_out
;mov si, prompt
;mov ah, 0x0f
;call str_out
wait_in:
in al, 0x60
cmp al, 0
jg end_wait_in
jmp wait_in
end_wait_in:
mov ax, 0
int 0x13
jc end_wait_in
read:
mov ax, 0x8000
mov es, ax
mov bx, 0
mov ah, 2
mov al, 1
mov ch, 0
mov cl, 2
mov dh, 0
int 0x13
jc read
jmp 0x8000:0x0000
head: db 'XordaOS Bootloader v0.0.1', 0xa, 0xa, 0x0
prompt: db 'Press any key to boot', 0x0
times 510 - ($ - $$) db 0
db 0x55
db 0xaa
This was my bootloader and now my kernel
jmp start
%include "console.inc"
start:
xor ax, ax
mov ds, ax
call init_console
call clrscr
mov si, msg
mov ah, 0x0f
call str_out
cli
jmp $
msg: db 'Hello World', 0x0
This is console.inc (commented in loader.asm with all console code)
init_console:
mov ax, 0xb800
mov es, ax
xor bx, bx
xor dx, dx
ret
str_out:
lodsb
cmp al, 0x0
je str_out_end
cmp al, 0xa
je new_line
mov [es:bx], ax
add bx, 2
jmp str_out
new_line:
add dx, 160
mov cx, dx
sub dx, bx
add bx, dx
mov dx, cx
jmp str_out
str_out_end:
ret
clrscr:
mov cx, 2000
xor bx, bx
mov al, ' '
mov ah, 0x00
start_clr:
mov [es:bx], ax
add bx, 2
loop start_clr
xor bx, bx
ret
then I entered following commands:
#!/bin/bash
nasm -fbin -o loader.bin loader.asm
nasm -fbin -o kernel.bin kernel.asm
dd if=/dev/zero of=XordaOS.img bs=1024 count=1440
dd if=loader.bin of=XordaOS.img bs=512 seek=0 conv=notrunc
dd if=kernel.bin of=XordaOS.img bs=512 seek=1 conv=notrunc
And then I started it in QEMU Launcher (GUI)
Everything is working until the code area where I load the kernel. After end_wait_in I called my clear screen function clrscr and the screen is cleared but after that my kernel doesn't do anything
I think something is wrong. Can anyone help me?
Given your original question, the disk read you are doing won't work on a number of emulators if the read is of a sector that doesn't have at least a sector worth of data in it (in this case a sector is 512 bytes). Emulator disk reads will usually return some type of error if there is an attempt to read an incomplete sector from a disk image.
To get around this I often just create a 1.44MB disk image with something like:
dd if=/dev/zero of=XordaOS.img bs=1024 count=1440
This creates a zero filled file of 1024*1440 bytes, the size of a 1.44MB floppy. Many emulators will automatically determine the disk type from such a file size which is a bonus. You then need to add each part of the bootloader and kernel into the image without truncating it after each write (using DD's conv=notrunc
option. You can do that with:
dd if=loader.bin of=XordaOS.img bs=512 seek=0 conv=notrunc
dd if=kernel.bin of=XordaOS.img bs=512 seek=1 conv=notrunc
When doing a disk read with Int 13h/ah=2h DL is the drive number. In your code you hard code it to 0 by placing 0 in DL. You should consider using the value passed to the bootloader by the BIOS in DL. You can save that value and restore it when needed for disk operations. As it is your code will only work on drive 0 (usually floppy disk A:).
When you finally get the kernel loaded at 0x8000:0x0000 and you FAR JMP to it you need to ensure that DS is properly set. In this case you need to have 0x8000 in DS.
I have a number of bootloader tips some of which you may wish to consider.
To debug real mode bootloaders and other 16-bit real mode code I recommend using BOCHS which has proper real mode debugging support. You can use QEMU with remote debugging but it has limitations and pitfalls. You can get some ideas on debugging 16-bit code in QEMU in my other Stackoverflow Answer.