Page 1 of 1

[SOLVED] ARM (Raspi) w/QEMU and ELF: Registers not set

Posted: Sun Jan 17, 2016 11:17 am
by TyrelHaveman
Hey guys! It's been a long time since I've posted here. I recently became interested in writing a fresh OS, this time for ARM (specifically Raspberry Pi), having previously done x86 and x86_64 systems.

I followed the bare bones stuff on the wiki and I am able to run it with the raspi fork of QEMU as shown at the very bottom.

However, the registers r1 and r2 are not getting set to the expected values (0xC42 and start of ATAGS, respectively). Browsing through the source code for QEMU I can definitely see stuff for setting up ATAGS, so why aren't I seeing it?

I realize that this is stuff that's normally done by a bootloader and I'm not really using a bootloader if I'm loading my kernel as an ELF directly with QEMU, but I thought it would pretend to be a bootloader in that case and get that all setup, as it appears to do in its source.

Anyone have any experience with this? Ideas?

Thanks!

Re: ARM (Raspi) w/QEMU and ELF: Registers not set

Posted: Sun Jan 17, 2016 1:48 pm
by jnc100
As I recall, it specifically does not set the registers if the file passed by the -kernel option is an ELF file. It only does if it thinks the loaded kernel is Linux (i.e. a flat binary).

Regards,
John.

Re: ARM (Raspi) w/QEMU and ELF: Registers not set

Posted: Sun Jan 17, 2016 3:39 pm
by TyrelHaveman
Thanks, John. That was it. Everything is super happy now, including me! :-)

Re: [SOLVED] ARM (Raspi) w/QEMU and ELF: Registers not set

Posted: Mon Jul 29, 2024 4:31 am
by ldelabre
After banging my head against the wall for a very-long day ; my many thanks John for your answer.

I still don't get why the start address is different 0x10000 under QEMU, 0x8000 on real hardware ?!

Regards,
Ludovic.

Re: [SOLVED] ARM (Raspi) w/QEMU and ELF: Registers not set

Posted: Mon Jul 29, 2024 1:46 pm
by Octocontrabass
QEMU loads flat binaries to 0x8000 (or 0x80000), exactly the same as real hardware.

QEMU loads ELF binaries to the address specified in the headers. Real hardware doesn't support ELF.

It sounds like you're trying to load an ELF binary in QEMU instead of a flat binary.

Re: [SOLVED] ARM (Raspi) w/QEMU and ELF: Registers not set

Posted: Tue Jul 30, 2024 4:19 am
by ldelabre
Octocontrabass wrote: Mon Jul 29, 2024 1:46 pm QEMU loads flat binaries to 0x8000 (or 0x80000), exactly the same as real hardware.

QEMU loads ELF binaries to the address specified in the headers. Real hardware doesn't support ELF.

It sounds like you're trying to load an ELF binary in QEMU instead of a flat binary.
Hi there,
Thanks for your message.

Strange, when I invokes QEMU with an ELF image

Code: Select all

qemu-system-arm -s -S -m 512 -M raspi1ap -kernel kernel/kernel.elf
And conect gdb, It does directly start at the 0x00010000 address ; and r0, r1 & r2 are sets to 0 (as expected).

But when I run QEMU with the same flatten binary image (using objcopy):

Code: Select all

qemu-system-arm -s -S -m 512 -M raspi1ap -kernel kernel.img
Now gdb start at address 0x00000000, then jumps to 0x00000420 (apparently the content board_setup_blob from hw\arm\boot.c), then back to 0x0000000c which matches to "bootloader" found in hw\arm\boot.c

Code: Select all

(gdb) x/4i $pc
=> 0xc: mov     r0, #0
   0x10:        ldr     r1, [pc, #4]    @ 0x1c
   0x14:        ldr     r2, [pc, #4]    @ 0x20
   0x18:        ldr     pc, [pc, #4]    @ 0x24
(gdb) x/8x $pc
0xc:    0xe3a00000      0xe59f1004      0xe59f2004      0xe59ff004
0x1c:   0x00000c42      0x00000100      0x00010000     0x00000000
Which will sets up correctly r0, r1 and r2 registers, but jump to 0x00010000 instead of the expected 0x8000.

Code: Select all

static const ARMInsnFixup bootloader[] = {
    { 0xe28fe004 }, /* add     lr, pc, #4 */
    { 0xe51ff004 }, /* ldr     pc, [pc, #-4] */
    { 0, FIXUP_BOARD_SETUP },
#define BOOTLOADER_NO_BOARD_SETUP_OFFSET 3
    { 0xe3a00000 }, /* mov     r0, #0 */
    { 0xe59f1004 }, /* ldr     r1, [pc, #4] */
    { 0xe59f2004 }, /* ldr     r2, [pc, #4] */
    { 0xe59ff004 }, /* ldr     pc, [pc, #4] */
    { 0, FIXUP_BOARDID },
    { 0, FIXUP_ARGPTR_LO },
    { 0, FIXUP_ENTRYPOINT_LO },
    { 0, FIXUP_TERMINATOR }
};
I also found this (still in hw\arm\boot.c) :

Code: Select all

#define KERNEL_LOAD_ADDR   0x00010000
#define KERNEL64_LOAD_ADDR 0x00080000
And it seems that others have face the same issue like the rpi-boot project which has two linker scripts: linker-qemu.ld linker.ld with only the base address changing.

So I'm probably missing something here.
Any help would be appreciated.

Regards,
Ludovic.

Re: [SOLVED] ARM (Raspi) w/QEMU and ELF: Registers not set

Posted: Tue Jul 30, 2024 8:46 am
by Octocontrabass
I think I figured out why it's not working. It looks like QEMU expects you to specify your flat binary using "-bios" instead of "-kernel". Which is a really weird way to do it, but it kinda makes sense for the Raspberry Pi.

Re: [SOLVED] ARM (Raspi) w/QEMU and ELF: Registers not set

Posted: Thu Aug 01, 2024 4:56 am
by ldelabre
Octocontrabass wrote: Tue Jul 30, 2024 8:46 am I think I figured out why it's not working. It looks like QEMU expects you to specify your flat binary using "-bios" instead of "-kernel". Which is a really weird way to do it, but it kinda makes sense for the Raspberry Pi.
Thank again for taking of your the time to respond.
So I did try it out

Code: Select all

qemu-system-arm -s -S -m 512 -M raspi1ap -bios kernel.img
But my GDB session turned quite short, the "bios" image was loaded at 0x8000, but the CPU starts @ 0x0 with uninitialized memory :

Code: Select all

(gdb) x/5i 0x8000
   0x8000:      ldr     r5, [pc, #56]   @ 0x8040
   0x8004:      mov     sp, r5
   0x8008:      ldr     r4, [pc, #52]   @ 0x8044
   0x800c:      ldr     r9, [pc, #52]   @ 0x8048
   0x8010:      mov     r5, #0
(gdb) x/5i $pc
=> 0x0: andeq   r0, r0, r0
   0x4: andeq   r0, r0, r0
   0x8: andeq   r0, r0, r0
   0xc: andeq   r0, r0, r0
   0x10:        andeq   r0, r0, r0
arm_write_bootloader() is not called from arm_setup_firmware_boot() ; so no standard bootloader is at @0x0.

I think I will go ask the QEMU mailing list for this.

Thanks again,
Regards,
Ludovic.