qemu-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Please help.. I wish to load .elf file directly for baremetal run..


From: ckim
Subject: RE: Please help.. I wish to load .elf file directly for baremetal run..
Date: Wed, 24 Mar 2021 21:48:45 +0900

Hello all,

 

I managed to make the baremetal program run using pflash in address 0~64KB and RAM starting from 0x40000000.

(I wanted to reply as a follow-up to Jakob Bohm’s reply to my question, but I didn’t receive his email. It’s only in the email archive.

His suggestion was that I have to do as I really have to do on a real bare-metal machine but it looked much more difficult so I devised a trick which I’ll explain below.)

 

  1. Prepare pflash.img

In my case, when I analyze the test.elf file, I could see two programs listed from program header.

Program loading is per program(=segment), not per section in .elf file.

This is the Program Headers output of “readelf -lW test.elf” command.

 

Program Headers:

  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align

  LOAD           0x010000 0x0000000000000000 0x0000000000000000 0x013bc8 0x013bc8 R E 0x10000

LOAD           0x030000 0x0000000040000000 0x0000000040000000 0x011178 0x0114cc RW  0x10000

From the ‘sections to segment mapping’ output of the readelf, I could see all .text and .rodata sections are in the first program (program #0),

and .data other read/write sections are grouped into the second program (program #1).

 

The first one (program #0) is for pflash (or ROM) starting at 0. Its size is 0x013bc8.

The second one (program #1) is for RAM starting at 0x40000000. Its MemSize size is 0x011178 (its file size is smaller because program #1 contains .bss section, uninitialized data, which doesn’t need to take space in the file).

 

Now make the pflash.img file using the program #0 like this.

(program #0 is read-only data like .text. In the test.elf file, offset 0x010000 = 65536, size 0x013bc8 = 80840, but I used size 0x18000 = 98304, it won’t hurt to copy some more data to pflash)

 

dd skip=65536 count=98304 if=test.elf of=pflash.img bs=1

truncate -s 67108864 pflash.img   (the pflash size is 64MB in ‘virt’ machine)

 

  1. Block arm_setup_firmware_boot

And in arm_load_kernel function in hw/arm/boot.c , change as below. (block arm_setup_firmware_boot)

 

if (!info->kernel_filename || info->firmware_loaded) {

        arm_setup_firmware_boot(cpu, info);

    } else {

        arm_setup_direct_kernel_boot(cpu, info);

    }

  •  

if (0) { // (!info->kernel_filename || info->firmware_loaded) {

        arm_setup_firmware_boot(cpu, info);

    } /* else */ {

        arm_setup_direct_kernel_boot(cpu, info);

    }

 

  1. Block loading program #0 into RAM which is meant for pflash region

In include/hw/elf_ops.h, in function load_elf64, (it’s shown as glue(load_elf, SZ) near line 315. Version 5.1.0)

(this is skipping program #0 from being loaded, which is provided by pflash)

 

total_size = 0;

    for(i = 0; i < ehdr.e_phnum; i++) {

        ph = &phdr[i];

        if (ph->p_type == PT_LOAD) {

  •  

total_size = 0;

    for(i = 1; i < ehdr.e_phnum; i++) {

        ph = &phdr[i];

        if (ph->p_type == PT_LOAD) {

 

  1. Run qemu-system-aarch64

The command I used is : (it provides both -kernel and -drive if=pflash options. With the modifications above, it just runs ok.)

qemu-system-aarch64 -machine type=virt,gic-version=3,secure=true,virtualization=true -cpu cortex-a72 -nographic -smp 1 -m 2048 -semihosting -kernel test.elf -drive if=pflash,file=pflash.img,format=raw,readonly=on

 

I know this is not a normal method but it suffices my current need because I don’t have enough time.

Hope this might be helpful to someone!

Thank you.

 

Chan Kim

 

From: ckim@etri.re.kr <ckim@etri.re.kr>
Sent: Wednesday, March 17, 2021 4:35 PM
To: 'qemu-discuss' <qemu-discuss@nongnu.org>
Subject: RE: Please help.. I wish to load .elf file directly for baremetal run..

 

 

If I change the linker script so that the program loads and starts at RAM address, I can use -kernel test.elf and run the program.

But Im still curious if I can load the program at 0x0 (ROM area) and use some data at 0x40000000 (RAM) like we can do in rtl simulation.

Thanks!

Chan Kim

 

From: ckim@etri.re.kr <ckim@etri.re.kr>
Sent: Wednesday, March 17, 2021 3:29 PM
To: 'qemu-discuss' <qemu-discuss@nongnu.org>
Subject: Please help.. I wish to load .elf file directly for baremetal run..

 

Hello all,

 

Using the help from this email list, Im using command below for my baremetal program test on qemu. (-s -S for connecting with gdb) :

 

$aarch64-none-elf-objcopy -O binary test.elf test.bin

$cp test.bin pflash.img; truncate -s 67108864 pflash.img        //to cut it down to 64MB because the pflash size is 64MB)

$qemu-system-aarch64 -machine type=virt,gic-version=3,secure=true,virtualization=true -cpu cortex-a72 -nographic -smp 1 -m 2048 -drive if=pflash,file=pflash.img,format=raw,readonly=on -s -

 

The entry address is 0. The problem is this test.bin can become very big when I have some space between section.

For example, if I want to put some initialized data (that can be changed) in RAM at 0x40000000, this bin file becomes bigger than 1GB. (because it fills the in-between spaces in .bin file)

I tried just using -kernel test.elf but it errors in rom_check_and_register_reset() inside qemu_init.

And the arm64 virt machine places dtb in the first RAM area.

Isnt there any option though which I can just load the .elf file (each section to its address) and run from the entry address?

and is it possible to disable dtb loading at the first RAM address?

Thank you for any help.

 

Chan Kim

 


reply via email to

[Prev in Thread] Current Thread [Next in Thread]