the_summer
Posts: 16
Joined: Mon Mar 19, 2012 9:49 am

Start bare metal programs using u-boot

Sat Dec 26, 2015 1:35 pm

Hi,

I am trying to run an RTEMS application on the B+ using u-boot.
I build u-boot following the guide on http://elinux.org/RPi_U-Boot using Steve Warren's branch and mainline.
The tftp-server is running and I can load the binaries from withing u-boot.
However so far I failed to execute them. An RTEMS application is essentially a single binary, so it should be similar to a bare metal standalone application.
What I tried so far is with the ELF-file test.exe:

1. Loading the binary to address 0x8000 and jump to the address

Code: Select all

On host:
arm-rtems4.11-objcopy -O binary test.exe test.bin
On rpi:
dhcp 0x8000 test.bin
go 0x8000
2. Create an image and boot it from memory

Code: Select all

On host:
arm-rtems4.11-objcopy -O binary test.exe test.bin
mkimage -A arm -O rtems -T kernel -a 0x0008000 -e 0x00008040  -C none -n "RTEMS" -d test.bin test.img
On rpi:
dhcp ${kernel_addr_r} test.img
bootm ${kernel_addr_r} 
In both cases after the bootm/go command the control is transferred to the loaded application, but it is not executed (correctly).
If I use the bootloader5 from dwelch67 (https://github.com/dwelch67/raspberrypi ... otloader05) and copy the test.bin-file to 0x8000 via the serial line the execution works.

Has any of the you managed to run their program binary from within u-boot? Do I need to set another option or environment variable?

Cheers,

Jan

PS: Loading the raspbian kernel to ${kernel_addr_r} and starting it with bootz works too.

vsiles
Posts: 41
Joined: Wed Feb 04, 2015 10:04 am

Re: Start bare metal programs using u-boot

Mon Dec 28, 2015 1:03 pm

I don't have any problem to load my code using u-boot (by the way, you can use the mainstream uboot now, they can properly deal with rpi/rpi2). I noticed that you tried to "go 0x8000" but you created your .img using "mkimage -e 0x8040". Which is your binary entry point ? I always link my kernel with its entry point at 0x8000 so everything still works if I remove u-boot.

Are you sure the entry point of your binary is correctly setup ?

the_summer
Posts: 16
Joined: Mon Mar 19, 2012 9:49 am

Re: Start bare metal programs using u-boot

Mon Dec 28, 2015 3:56 pm

For the entry address in the mkimage command I tried both 0x8000 and 0x8040 (I found this address using readelf).
It did not change anything.
The "go" command I only used when dealing with a raw binary after arm-rtems4.11-objcopy.

Could you describe how you postprocess your elf-files and how you load/run them in u-boot?

vsiles
Posts: 41
Joined: Wed Feb 04, 2015 10:04 am

Re: Start bare metal programs using u-boot

Mon Dec 28, 2015 4:49 pm

I'm thinking that you're issue is not on how to "post process" elf files but rather how to create them in the first place.

When you ask u-boot to "dhcp 0x8000 foo.bin && go 0x8000" (I'll assume that you have compiled u-boot with the standard rpi config so ${kernel_addr_r} is also 0x8000) it will:
- copy foo.bin at the location 0x8000 in main memory
- set the [pc] register to 0x8000

That's all. If that's not your binary entry point as in "the first instructions that should be run in your program" then things won't work at all. To be sure that I have the relevant code there, I have a custom link script which will ensure the correct part of my code is there. Here is an example:

I have a boot.S file where my program starts, which looks like:

Code: Select all

.section ".text.boot"
.globl Start
Start:
    /* my assembly code that should run first 
     * mostly initialize my state so I can call C function instead of doing all in assemby code
     */
    ....
I compile this file and the other .c files to .o files. Then I use the following link script, linker.ld

Code: Select all

ENTRY(Start)
SECTIONS
{
    . = 0x8000;
    .text : {
        boot.o(*.text.boot)
        *(.text*)
     }
     .data : { *(.data*) }
     . = ALIGN(4);
     _bss_start = .;
     .bss : { *(.bss* COMMON) }
     . = ALIGN(4);
     _bss_end = .;
}
Basically, I am asking the link to put my Start routine at the beginning of the code (at 0x8000) and the rest after, in any order, I don't really care. Same for data and bss, they come after as it pleases the linker. The important part is that my Start code will be at 0x8000 when I ask u-boot to "go 0x8000".
The linker can be invoked by

Code: Select all

$(CROSS_COMPILE)ld -T linker.ld *.o -o foo.elf
. You can turn the elf in a binary using

Code: Select all

$(CROSS_COMPILE)objcopy -O binary foo.elf foo.bin
.

I hope this helps,
V.

the_summer
Posts: 16
Joined: Mon Mar 19, 2012 9:49 am

Re: Start bare metal programs using u-boot

Mon Dec 28, 2015 5:34 pm

Thank you very much.
I will see what I can find out about the linker scripts. I assumed that the generated binaries would work fine, because they do if I simply copy them to the sd-card as kernel.img and they work with dwelch67's bootloader which simply writes the binary file from serial port to address 0x8000 and jumps there.

I hoped that u-boot would do the same, but much faster over ethernet.

I configured u-boot with "make rpi_defconfig". Default kernel_addr_r is 0x01000000 that's why I usually type 0x8000 manually. Could this be an issue?

vsiles
Posts: 41
Joined: Wed Feb 04, 2015 10:04 am

Re: Start bare metal programs using u-boot

Tue Dec 29, 2015 8:11 am

As I said, the location where you load the binary should match the entry point of your program. If u-boot's ${kernel_addr_r} is 0x01000000 you should dhcp 0x01000000 foo.bin && go 0x01000000, with a link script that links your binary to start at 0x01000000. If everything works fine when you replace kernel.img with your binary, dhcp 0x8000 & go 0x8000 should also work fine, I don't see why this would not work, sorry.

the_summer
Posts: 16
Joined: Mon Mar 19, 2012 9:49 am

Re: Start bare metal programs using u-boot

Wed Jan 20, 2016 9:57 pm

Hm, I haven't managed to make any progress in this matter.
Would you be able to just upload your uboot.img-file. Then I could check if I did something wrong setting up uboot or if my programs are not correctly linked.

Cheers,

Jan

pingaaas
Posts: 14
Joined: Sat Oct 17, 2015 8:08 pm

Re: Start bare metal programs using u-boot

Sun Dec 03, 2017 1:00 am

I am having the same problem... but the other way around. When I use U-boot it works fine. When I try to set the kernel variable in config.txt directly to the bare metal application binary it does not work.
BTW, I am checking if it works or not only by checking if the UART outputs a message. Can it have anything to do with UART clock set up? Maybe U-boot is setting up something I don't know about. (I am following this tutorial http://wiki.osdev.org/Raspberry_Pi_Bare_Bones ... It uses a 3MHz clock for the UART, so I add this in the init_uart_clock variable in config.txt)

Thank you in advance

Return to “Bare metal, Assembly language”