2

A few friends and I are working on a very simple kernel project. At the moment, we have a bootloader (using GNU assembly) and a simple kernel (C with no stdlib). I've been tasked with setting up a QEMU simulation to test the OS, but ran into several issues along the way.

I've gotten QEMU to boot, and I have created a bootable disk image.

Makefile:

%.o: %.S
    as -o $@ -c $<

bootsect: boot.o
    ld -o ./bin/bootsect.bin $^ -nostdlib -Ttext 0x7C00

img: bootsect
    dd if=/dev/zero of=boot.img bs=512 count=2880
    dd if=./bin/bootsect.bin of=boot.img conv=notrunc bs=512 count=1

I tried to run it with qemu-system-i386 -drive format=raw,file=boot.img I have also tried various ways of booting the image, but always end up with the same error:

Booting from Hard Disk:
     Boot failed: not a bootable disk

Here is the boot loader code if needed:

.code16
.org 0

.text

.global _start
_start:
    cli

    xorw %ax, %ax
    movw %ax, %es
    movw %ax, %ds
    movw %ax, %es
    movw %ax, %ss

    movw $0x3000, %sp

    sti

    movw $hello, %si
    call print

print:
    xorb %bh, %bh
    movb $0x0E, %ah

    lodsb

    cmpb $0, %al
    je 1f

    int $0x10;
    jmp print

1:
    ret

hello:
    .asciz "HELLO WORLD\n"

.org 510
.word 0xAA55

Where is the problem?

user3840170
  • 26,597
  • 4
  • 30
  • 62
Christian
  • 41
  • 7
  • If you want to make an ISO for some reason out of a boot sector this answer may be of interest https://stackoverflow.com/a/34275054/3857942 – Michael Petch Nov 01 '22 at 17:59
  • And yes, another issue is that this isn’t actually an ISO file, despite being named as such. Given that it has the size of a floppy image (2880 sectors), perhaps it is best treated as such, and given an extension like `.img` (as it typical). – user3840170 Nov 01 '22 at 18:13
  • Ah, thank you! I have plans to expand it into a proper ISO file for an OS, but atm it is better to call it a `.img` – Christian Nov 01 '22 at 18:15

1 Answers1

2

The linker is creating an ELF executable, not a raw binary. You need to extract the raw code contained in the .text section into a stand-alone file, without any wrapping object code format. Only then you can splice that file into the disk image as the boot sector.

There are two ways you can go about doing this. One is to add an extra step to the Makefile that invokes objcopy:

bootsect: bin/bootsect.bin

bin/bootsect.elf: boot.o
    ld -o $@ $^ -nostdlib -Ttext=0x7c00

%.bin: %.elf
    objcopy -Obinary -j.text $< $@

The other is to use a linker script. Put the following in a file named bootsect.ld:

OUTPUT_FORMAT("binary")

SECTIONS {
    .image 0x7c00 : {
        *(.text)
    }
}

And in the Makefile:

bin/bootsect.bin: boot.o bootsect.ld
    ld -o $@ boot.o -nostdlib -Tbootsect.ld

To check that this works, run file bin/bootsect.bin. It should output ‘DOS/MBR boot sector’.

user3840170
  • 26,597
  • 4
  • 30
  • 62