assemblyx86-64nasmosdevbochs

bochs: can not load bootloader using a floppy image


I have a simple (probably the simplest) bootloader. Very similar to this and this. The code is shown below

[org  0x7c00]

mov ah, 0x0e
mov al, 'h'

int 0x10

jmp  $

times  510-($-$$)  db  0

dw  0xaa55

The code is taken from the video series tutorial from here.

I have tried everything to compile and load this bootloader using bochs. But whatever I do, I get a black screen like the following

enter image description here

Nothing comes on the screen and after a bit I get that bochs is not responding.

My present approach to load the image is -

  1. nasm boot_simple.asm -f bin -o boot.bin

  2. dd if=boot.bin of=boot.img bs=512

  3. bochs -f /dev/null -q 'display_library: sdl2' 'boot:a' 'floppya: 1_44=boot.img, status=inserted'

I tried many other approaches (slight variations of the above) (even tried to compile and load a separate bootloader from here) But nothing worked. Always the same black screen and does not show any other information.

I am becoming mad. What am I missing?

Ubuntu 22.04

Bochs version: Bochs x86 Emulator 2.7 (installed via sudo apt install)

I am super new to OS development and I want to learn it as a side project. Please help me getting started. Could not find suitable information anywhere.


Checking the log I see the following

00000000000i[FLOPPY] fd0: 'boot.img' ro=0, h=2,t=80,spt=18
00000000000i[FLOPPY] Using boot sequence floppy, none, none
00000000000i[FLOPPY] Floppy boot signature check is enabled

Not sure how to interpret this (if this is normal or some kind of error / mistake is hiding in them)


Tried to follow these steps as per here and here which I believe should create a simple 1.44 MB image, place the bin in the first sector and leave it to it. When done in this way (as well not padding it) in both cases qemu loads the image and shows the h each time without fault. Bochs does not load anything. Whatever I do. Always the same black screen and afterwards Not responding

I uninstalled, purged, and then reinstalled bochs. I do not know what else I can do. I can't understand why it fails to load the simple bootloader.


Here are the steps

  1. nasm boot_simple.asm -f bin -o boot.bin

  2. dd if=/dev/zero of=floppy.img bs=1024 count=1440

  3. dd if=boot.bin of=floppy.img seek=0 count=1 conv=notrunc

  4. mkfs.vfat -F 12 ./floppy.img (This step makes the floppy un-bootable in qemu but really does not change anything for bochs)

  5. bochs -f /dev/null -q 'display_library: x' 'boot:floppy' 'floppya: 1_44=floppy.img, status=inserted' 'romimage: file=/usr/share/bochs/BIOS-bochs-latest' 'error: action=report'

But nothing happens. Bochs boots to a black screen.


Ok I have a slight idea. It seems that for some reason bochs halts at the first line of the code.

Printing something like this -

Next at t=0
(0) [0x0000fffffff0] f000:fff0 (unk. ctxt): jmpf 0xf000:e05b          ; ea5be000f0
<bochs:1>

Then waiting at the prompt <bochs:1>. If I do step there it does step through some instructions. Is there something I am missing here? Is there a bug in my code?


Trying to use seabios.bin with the default bochs vgabios brings me to this state

enter image description here

This is my bochs config file -

romimage: file="/usr/share/seabios/bios.bin"
vgaromimage: file ="/usr/share/bochs/VGABIOS-lgpl-latest"
floppya: 1_44=floppy.img, status=inserted
boot: a
display_library: x,
log: bochsout.txt

With this option I am able to get rid of the not-responding part. A small advancement. (using seabios) but it still does not display anything. So, I have checked from the menu and it is detecting the floppy in fd0. I am suspecting the vgabios is also not working And hence I do not see anything? Well I am a bit lost to be frank. But as comments say, I think it is not a normal case.


Debug log when trying to set breakpoint

With seabios

    <bochs:1> b 0x7c00
<bochs:2> c
(0) Breakpoint 1, 0x0000000000007c00 in ?? ()
Next at t=16650931
(0) [0x000000007c00] 0000:7c00 (unk. ctxt): mov ah, 0x0e              ; b40e
<bochs:3> n
Next at t=16650932
(0) [0x000000007c02] 0000:7c02 (unk. ctxt): mov al, 0x68              ; b068
<bochs:4> n
Next at t=16650933
(0) [0x000000007c04] 0000:7c04 (unk. ctxt): int 0x10                  ; cd10
<bochs:5> n
Next at t=16650935
(0) [0x000000007c06] 0000:7c06 (unk. ctxt): jmp .-2  (0x00007c06)     ; ebfe
<bochs:6> n
Next at t=16650936
(0) [0x000000007c06] 0000:7c06 (unk. ctxt): jmp .-2  (0x00007c06)     ; ebfe
<bochs:7> n
Next at t=16650937
(0) [0x000000007c06] 0000:7c06 (unk. ctxt): jmp .-2  (0x00007c06)     ; ebfe
<bochs:8> n
Next at t=16650938
(0) [0x000000007c06] 0000:7c06 (unk. ctxt): jmp .-2  (0x00007c06)     ; ebfe

So the breakpoint works. But, no display

With Bochs default bios

<bochs:1> b 0x7c00
<bochs:2> c
bx_dbg_read_linear: physical memory read error (phy=0x0000322f3130, lin=0x00000000322f3130)
Next at t=688972
(0) [0x0000fffffff0] f000:fff0 (unk. ctxt): jmpf 0xf000:e05b          ; ea5be000f0
<bochs:3> n
Next at t=688973
(0) [0x0000000fe05b] f000:e05b (unk. ctxt): xor ax, ax                ; 31c0
<bochs:4> n
Next at t=688974
(0) [0x0000000fe05d] f000:e05d (unk. ctxt): out 0x0d, al              ; e60d
<bochs:5> n
Next at t=688975
(0) [0x0000000fe05f] f000:e05f (unk. ctxt): out 0xda, al              ; e6da
<bochs:6> n
Next at t=688976
(0) [0x0000000fe061] f000:e061 (unk. ctxt): mov al, 0xc0              ; b0c0
<bochs:7> n
Next at t=688977
(0) [0x0000000fe063] f000:e063 (unk. ctxt): out 0xd6, al              ; e6d6
<bochs:8> n
Next at t=688978
(0) [0x0000000fe065] f000:e065 (unk. ctxt): mov al, 0x00              ; b000
<bochs:9> n
Next at t=688979
(0) [0x0000000fe067] f000:e067 (unk. ctxt): out 0xd4, al              ; e6d4
<bochs:10> n
Next at t=688980
(0) [0x0000000fe069] f000:e069 (unk. ctxt): mov al, 0x0f              ; b00f
<bochs:11>

I DID IT!! I downloaded and compiled bochs from source on my platform. I could not make sdl compile (--with-sdl did not work, even after installing sdl2-dev) but rest is good. So I guess the apt-get install is broken for Ubuntu 22.04 (at least)

Thanks a lot for all your help. It was a great learning session.


Solution

  • BOCHS will always stop at the first instruction in the BIOS when launched. The first instruction is at 0xf000:0xfff0 which is what you see in the output. This gives you a chance to set breakpoints ahead of time. For example b 0x7c00 would break at the first instruction of the bootloader if you wished. To start running just use the command c to continue.