Home > Net >  Where does QEMU load the DTB?
Where does QEMU load the DTB?

Time:11-26

I am writing my own bootloader for aarch64 that must boot linux, and in order to execute it properly I need to follow the linux boot protocol.

Here are some memory mappings: located in my linker file

FLASH_START = 0x000100000;
RAM_START = 0x40000000;
TEXT_START = 0x40080000;

Here is the command I am using to lauch my virt, giving 4 cores and 2GB of RAM

qemu-system-aarch64 -nographic -machine virt -cpu cortex-a72 -kernel pflash.bin  -initrd initramfs.cpio.gz -serial mon:stdio -m 2G -smp 4

The pflash.bin has the following layout:

    dd if=/dev/zero of=pflash.bin bs=1M count=512
    dd if=my_bootloader.img of=pflash.bin conv=notrunc bs=1M count=20
    dd if=Kernel of=pflash.bin conv=notrunc bs=1M seek=50

Where: Kernel is the linux kernel image file,

and my_bootloader.img is simply the objcopy of the elf file: aarch64-linux-gnu-objcopy -O binary my_bootloader.elf my_bootloader.img

And the elf file is created in the following manner:

aarch64-linux-gnu-ld -nostdlib -T link.ld my_bootloader.o -o my_bootloader.elf

Here is my_bootloader.S

.section ".text.startup"

.global _start
_start:
    ldr x30, =STACK_TOP
    mov sp, x30
    ldr x0, =RAM_START
    ldr x1, =0x43280000
    br x1
    ret

As you can see All I have done so far is:

  1. Set up the stack
  2. Presumably I have loaded the DTB to the x0 (just like the linux boot protocol demands)
  3. Branch to the location of the linux kernel

So I have not yet loaded the initramfs.cpio.gz which contains the file system but I should already normally get at least some output from the kernal since the DTB was loaded.

My question is, have I loaded it correctly? And I guess that the simple answer is no. But basically I have no clue where qemu puts the dtb in my RAM, and after looking everywhere on the documentation I cannot seem to find this information.

I would much appreciate if someone could tell me where QEMU loads the dtb so I can put it into x0 and the kernel could gladly read it!

Thanks in advance!

CodePudding user response:

Where the dtb (if any) is is board specific. The QEMU documentation for the Arm 'virt' board tells you where the DTB is:

https://www.qemu.org/docs/master/system/arm/virt.html#hardware-configuration-information-for-bare-metal-programming

However, your command line is incorrect. "-kernel pflash.bin" says "this file is a Linux kernel, boot it in the way that the Linux kernel should be booted". What you want is "load this file into the flash, and start up in the way that the CPU would start out of reset on real hardware". For that you want one of the other ways of loading a guest binary (-bios is probably simplest). And you probably don't want to pass QEMU a -initrd option, either, since that is intended for either (a) QEMU's builtin bootloader or (b) QEMU-aware bootloaders that know how to extract a kernel and initrd from the fw-cfg device.

PS: If you tell QEMU to provide more than one guest CPU then your bootloader will need to deal with the secondary CPUs. That either means using PSCI to start them up, or else handling the fact that all the CPUs start executing the same code out of reset (which one depends on how you choose to start QEMU). You're better off sticking to '-smp 1' to start off with, and come back and deal with SMP later.

  • Related