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

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
TyrelHaveman
Member
Member
Posts: 40
Joined: Thu Sep 20, 2007 11:20 pm
Location: Bellingham, WA
Contact:

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

Post 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!
Last edited by TyrelHaveman on Sun Jan 17, 2016 3:40 pm, edited 1 time in total.
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

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

Post 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.
User avatar
TyrelHaveman
Member
Member
Posts: 40
Joined: Thu Sep 20, 2007 11:20 pm
Location: Bellingham, WA
Contact:

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

Post by TyrelHaveman »

Thanks, John. That was it. Everything is super happy now, including me! :-)
ldelabre
Posts: 3
Joined: Fri Jul 26, 2024 10:20 am
Libera.chat IRC: ldelabre
Location: France

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

Post 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.
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

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

Post 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.
ldelabre
Posts: 3
Joined: Fri Jul 26, 2024 10:20 am
Libera.chat IRC: ldelabre
Location: France

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

Post 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.
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

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

Post 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.
ldelabre
Posts: 3
Joined: Fri Jul 26, 2024 10:20 am
Libera.chat IRC: ldelabre
Location: France

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

Post 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.
Post Reply