1
votes

I've recently been getting into bare metal development for the Raspberry Pi 2, and having some success. Admittedly I've hesitated to buy an actual physical device until I feel I can do something useful with it, for the time being I've been emulating the device using qemu 2.11.0. So far I've developed multicore capabilities for my kernel, as well as simple Serial I/O, but I feel I'd like to get much further before working with a physical device.

My issue right now is that I'm trying to learn how to place my kernel onto an SD card image and boot qemu-system-arm from that SD card image, so I can properly emulate a kernel loaded from the raspberry pi 2 bootloader.

I've gotten as far as grabbing the SD card contents from https://github.com/raspberrypi/firmware ... aster/boot, and using the following script to create the image and load my kernel into it. I've seen that people have figured out how to load Raspbian from an emulated SD card, so I figure I can do the same.

#!/bin/bash

OUTPUT_IMG=os.img
OUTPUT_IMG_SIZE=40
TEMP_MOUNT_DIR="$(mktemp -d)"
# the SD card boot partition contents are in this folder...
OUTPUT_IMG_CONTENTS_DIR="./sd"
OS_DIR="${HOME}/os"
OS_BINARY="${OS_DIR}/kernel.bin"

dd if=/dev/null of=${OUTPUT_IMG} bs=1M seek=${OUTPUT_IMG_SIZE}
mkfs.fat -F 32 ${OUTPUT_IMG}
sudo mount -t vfat -o loop ${OUTPUT_IMG} ${TEMP_MOUNT_DIR}
make -C ${OS_DIR} clean
make -C ${OS_DIR}
sudo cp -r ${OUTPUT_IMG_CONTENTS_DIR} ${TEMP_MOUNT_DIR}
sudo cp ${OS_BINARY} "${TEMP_MOUNT_DIR}/kernel.img"

The only issue is that qemu doesn't seem to boot from this image using the following command:

qemu-system-arm -machine raspi2 -serial file:serial.log -sd ./dev/os.img

I've tried a few different combinations, but to no avail.

I can see from hooking GDB that the kernel is simply not booting from this card image. Loading the kernel directly into qemu with the -kernel argument works otherwise perfectly.

I was wondering if anyone here had any insight on how to accomplish this! Any help here would be greatly appreciated!

2

2 Answers

2
votes

Your command won't work because you haven't passed QEMU either a guest BIOS or a guest kernel to run. The QEMU arm boards aren't like the x86 PC machine, which always automatically runs a guest BIOS image. If you want to run a BIOS (probably UEFI?) you need to find a suitable BIOS blob and pass it to QEMU with the -bios argument. Then QEMU will run the BIOS code, which will hopefully include SD card drivers to load the kernel and so on off the SD card.

Just using -kernel is much simpler...

1
votes

After doing a bit of reading and searching online, as well as a bit of help from other contributors such as Peter Maydell with his answer above, I think I've answered my own question. Unless I'm mistaken qemu-system-arm does not fully emulate the Raspberry Pi boot process, and instead just loads the kernel specified with the -kernel argument by loading the binary into the guest system's memory and jumping to the entry point. It doesn't look like any additional hardware bootloading is emualted for -M raspi2 unfortunately.

Can ARM qemu system emulator boot from card image without kernel param? This question is similar and contains some more useful details on this issue, relating to qemu-system-arm as a whole..