I am trying to write a sample “Hello World” in real mode that will run in QEMU. The host is a 64 bits intel running FreeBSD 14.
I have tried the following:
This is boot.asm
file:
format binary
org 0x7C00 ; Bootloader loaded at 0x7C00
start:
; Set up segment registers
mov ax, cs
mov ds, ax
mov es, ax
; Set up stack
mov ax, 0x0000
mov ss, ax
mov sp, 0x7C00
; Print message using BIOS interrupt
mov si, msg
print_loop:
lodsb ; Load next character
test al, al
jz halt ; Jump if null terminator
mov ah, 0x0E ; BIOS teletype function
int 0x10 ; Call BIOS
jmp print_loop
halt:
cli ; Disable interrupts
hlt ; Halt processor
msg db "Hello, World!", 0
times 510 - ($-$$) db 0 ; Pad to 510 bytes
dw 0xAA55 ; Boot signature
This is the makefile:
# Makefile for FreeBSD bootloader example
ASM = fasm
QEMU = qemu-system-i386
TARGET = boot.bin
SOURCE = boot.asm
all: $(TARGET)
$(TARGET): $(SOURCE)
$(ASM) $(SOURCE) $(TARGET)
run: $(TARGET)
$(QEMU) -fda boot.bin -serial stdio -display none
clean:
rm -f $(TARGET)
This is what I get when I assemble the file and run it through qemu:
$ make
fasm boot.asm boot.bin
flat assembler version 1.73.32 (16384 kilobytes memory)
2 passes, 512 bytes.
$ make run
qemu-system-i386 -fda boot.bin -serial stdio -display none
WARNING: Image format was not specified for 'boot.bin' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
Some questions:
As for question (1), you are printing output to the screen, not to the serial console. So it's clear that no output is produced on the serial console. If you want output to appear on the serial console, use service INT 14h/AH=01H SEND CHARACTER. Or use -display curses
to display the video output on the console.
As for question (2), use -drive format=raw,file=boot.bin,if=floppy
instead of -fda boot.bin
.