I’m writing a simple OS. I’m having trouble with the output string in qemu screen, the screen just shows something like this (it only shows the output of the boot.asm
file, but the output of the kernel.c
file doesn’t show):
I have the following code:
boot.asm
[bits 16]
[org 0x7c00]
boot:
; Set up segments
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7c00
; Print a message
mov si, hello_msg
call print_string
; Load the kernel
mov bx, 0x1000 ; Load address
mov dh, 2 ; Number of sectors to read
mov dl, 0 ; Drive number (0 = floppy)
mov ch, 0 ; Cylinder number
mov cl, 2 ; Sector number (1-based, so start from 2)
mov ah, 0x02 ; BIOS read sector function
int 0x13 ; Call BIOS interrupt
; Jump to the kernel
jmp 0x1000
print_string:
lodsb
or al, al
jz done
mov ah, 0x0e
int 0x10
jmp print_string
done:
ret
hello_msg db 'Hello from bootloader!', 0x0D, 0x0A, 0
times 510-($-$$) db 0
dw 0xaa55
kernel.c
void kmain(void) {
const char *str = "Hello from kernel!";
char *vidptr = (char*)0xb8000;
unsigned int i = 0;
unsigned int j = 0;
while(j < 80 * 25 * 2) {
vidptr[j] = ' ';
vidptr[j+1] = 0x07;
j = j + 2;
}
j = 0;
while(str[i] != '') {
vidptr[j] = str[i];
vidptr[j+1] = 0x07;
++j;
++j;
++i;
}
while(1);
}
linker.ld
ENTRY(kmain)
SECTIONS
{
. = 0x1000;
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss) }
}
Makefile
all: os-image
boot.bin: boot.asm
nasm -f bin boot.asm -o boot.bin
kernel.o: kernel.c
gcc -m32 -c kernel.c -o kernel.o -ffreestanding
kernel.bin: kernel.o
ld -m elf_i386 -T linker.ld -o kernel.bin kernel.o
os-image: boot.bin kernel.bin
cat boot.bin kernel.bin > os-image
run: os-image
qemu-system-i386 -drive format=raw,file=os-image -monitor stdio
clean:
rm -f *.bin *.o os-image
The output seems that the kernel.c
file is not running, so how to solve this problem?