`tftp` command in U-Boot: Binary image or U-Boot image? - bootloader

When using the tftp command in U-Boot, do I have to specifiy a binary image to load, or an image created with the U-Boot-supplied mkimage tool?
Addendum: The image I'm trying to load is a bare-metal C program. I compiled it with
arm-none-eabi-gcc (input files and flags) -o blinky.elf
and converted it with
arm-none-eabi-objcopy -O binary blinky.elf blinky.bin
.

tftp command is just for downloading a file from the host, it does not care what to download. The bootm command is which does care. Recent versions of u-boot are capable of loading zImage directly (if configured). But the most common way is to use the legacy uImage, created either by mkimage or by make uImage command, if supported.
Upd:
For a bare-metal programs you should use the go command in u-boot with the address of your bin file:
tftp ${loadaddr} yourfile.bin
go ${loadaddr}
Upd2:
By the way, It is possible to build u-boot with a bootelf command, which will allow to boot from your output elf file, without the need of using objcopy.

Related

Cross compiled binary not running on RPI, did I compile it correctly?

I am trying to cross compile a small rust application for the RPI. I am cross compiling because compiling directly on the PI takes way too long and it hits 75C.
I followed various instructions, but what I ended up doing is this:
Install "armv7-unknown-linux-gnueabihf" target with rustup
Download rpi tools from here: https://github.com/raspberrypi/tools
Add the "tools/arm-bcm2708/arm-linux-gnueabihf/bin/" folder to PATH
Add ".cargo/config" file with:
[target.armv7-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"
run "cargo build --target armv7-unknown-linux-gnueabihf --release"
scp the file to the RPI
chmod +x the_file
do "./the_file"
I get bash: ./the_file: No such file or directory
Yes, I am indeed in the right directory.
So this is the output from "file":
ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically
linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.32,
with debug_info, not stripped
I'm not experienced enough with this sort of stuff to determine if the binary that I produced is suitable to be run on an RPI3 B.
Did I produce the correct "type" of binary?
P.S. I am running DietPi distro on the PI. It is based on debian if that's of any relevance.
So I solved this by cheating. I found https://github.com/rust-embedded/cross which took about 30 seconds to get going and now I can cross compile to pretty much anything. I highly recommend it!
The error message "No such file or directory" is not about the your executable but about the dynamic libraries linked to it which are missing from the target system.
To find out which libraries your executable needs you have to run the following command.
ldd /usr/bin/lsmem
This will output something like this
linux-vdso.so.1 (0x00007fffc87f1000)
libsmartcols.so.1 => /lib/x86_64-linux-gnu/libsmartcols.so.1 (0x00007fe82fe71000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe82fc7f000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe82fedd000)
Now you have to check that all this libraries are available on your system. rust-cross probably uses the correct linker for your target so that is probably the reason this works with it. To modify the linker see https://stackoverflow.com/a/57817848/5809980

Why can't I run custom application on my Beaglebone board? [duplicate]

This question already has answers here:
what does "-sh: executable_path:not found" mean
(2 answers)
Closed 3 years ago.
I have cross-compiled the small application for my beaglebone board:
/* led_test.c */
int main(int argc, char const *argv[])
{
return 0;
}
Compiling was done successfully, but if I try to run the application in target board, I get this:
# cd /bin/
# ls -la | grep led_test
-rwxr-xr-x 1 default default 13512 Feb 5 2020 led_test
# led_test
-sh: ./led_test: not found
Why can't I run custom application on my Beaglebone board? Could anyone explain me it, please?
Some information about my environment:
1. work-station: Ubuntu 18.04.4 LTS x86-64
2. target machine: ARMv7 beaglebone board
3. cross-compiler: gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf
4. I built u-boot and Linux kernel with this toolchain and mounted rootfs via NFS.
UPD 1:
I tried use this ./led_test instead led_test. It doesn't matter, because my application is placed into /bin directory.
It's likely your userspace was not built with the cross-toolchain that you compiled your binary with. Maybe you compiled the kernel with it, but that does not matter, what matters is the rootfs.
Your program is dynamically linked. When the program runs, the kernel really loads the dynamic linker, and that then maps the executable into the process's address space along with the libraries.
To see the dynamic linker, run readelf -l on your host or target system on the binary. Example:
$ readelf -l a.out
Elf file type is EXEC (Executable file)
[... more lines ...]
[Requesting program interpreter: /lib/ld-linux-armhf.so.3]
[... more output ...]
The line with program interpreter is the one to look file. file will also give this information. It's probably the case the the file named here is not preset on your rootfs. That is the "file not found" that the error is from.
What you need to do is use the correct cross-toolchain (which uses the same C library version) for the rootfs you are using or build a new rootfs with the same toolchain.
Take a look at buildroot for an easy way to make a new, simple, BeagleBone Black rootfs that's way faster and simpler than using Yocto/Poky to make one.
try run by absolute path, or if you in directory run as ./led_test
Also, show output from file
file /bin/led_test
Or run application with gdb

Kernel panic - not syncing: Requested init /linuxrc failed (error -2)

I build an embedded linux with YOCTO for the KARO TX6S-8035 target. I use the
Mfgtools-TX6-2018-01 tool to flash images into the board but when i boot the device i have the following error: Kernel panic - not syncing: Requested init /linuxrc failed (error -2).
How can i fix this?
Here is the result of printenv from U-BOOT:
printenv
And the serial output from the board: serial output
The kernel is looking for the init program and cannot find it. Most likely your image is corrupt. More info here: What is linuxrc purpose and is it needed in the rootfs?
I would try:
reflash the image
check the image to be sure that linuxrc exists
post a questions to the meta-freescale mailing list
Also, I do not know what setup you are using, but I would look at the FSL Community BSP. There is a good chance others are building for that platform.
Kernel panic - not syncing: Requested init /linuxrc failed (error -2)
In my case, I create initrd with busybox. /linuxrc execute error, because of it can't find the dynamic library.
execute below script after mount the initrd
file linuxrc
linuxrc: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, stripped
Fix-Option1:
copy library to initrd.
mkdir -p $WORKSPACE/initrd
mount $WORKSPACE/ramdisk.img $WORKSPACE/initrd -t ext2 -o loop=/dev/loop0
pushd $WORKSPACE/initrd/
cp -rf /opt/buildtools/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/lib ./
cp -rf /opt/buildtools/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/lib64 ./
aarch64-none-linux-gnu-strip $WORKSPACE/initrd/lib/*
aarch64-none-linux-gnu-strip $WORKSPACE/initrd/lib64/*
aarch64-none-linux-gnu-strip $WORKSPACE/initrd/bin/busybox
popd
umount $WORKSPACE/initrd
gzip -9 $WORKSPACE/ramdisk.img
Fix-Option2:
build busybox statically.
make -j16 -C $WORKSPACE/$BUSYBOX ARCH="arm64" LDFLAGS="--static" CROSS_COMPILE="aarch64-none-linux-gnu-" install
busybox-1.32.1/_install/bin/busybox: ELF 64-bit LSB executable, ARM aarch64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.7.0, stripped

Booting custom kernel on xeon-phi

I am trying to boot a custom kernel on Xeon-phi instead of the default Linux kernel. At this link, I found a way to cross compile my kernel which compiles successfully using k1om-mpss-linux-gcc cross compiler. Is cross compiling enough ? I get the error
mykernel.img is not a k1om Linux bzImage
Edit:
So, I used /usr/linux-k1om-4.7/bin/x86_64-k1om-linux-gcc compiler to compile a simple helloworld.c program and the kernel source. I get two different types of results for objdump -f on the executables.
for helloworld.c:
hello: file format elf64-k1om
architecture: k1om, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x0000000000400400
for mykernel:
mykernel: file format elf32-i386
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x0010000c
I compiled using the same compiler, yet they show different architectures. What is the reason for this ?
The first thing to do is figure out what mykernel.img is. Try running file on it.
$ file /opt/mpss/3.4/sysroots/k1om-mpss-linux/boot/vmlinux-2.6.38.8+mpss3.4
/opt/mpss/3.4/sysroots/k1om-mpss-linux/boot/vmlinux-2.6.38.8+mpss3.4: ELF 64-bit LSB executable, version 1 (SYSV), statically linked, BuildID[sha1]=0xa4c16ee85c11aca4e78dc4ae46d3827fb74289c1, not stripped
$ objdump -f /opt/mpss/3.4/sysroots/k1om-mpss-linux/boot/vmlinux-2.6.38.8+mpss3.4
/opt/mpss/3.4/sysroots/k1om-mpss-linux/boot/vmlinux-2.6.38.8+mpss3.4: file format elf64-k1om
architecture: k1om, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x0000000001000000
The answer to your original question - no, unfortunately, it is not as simple as just cross-compiling. There were a number of changes made to the kernel that comes with the MPSS. I don't know all the changes but a big one that I do know is that they had to add support for the larger register set on the coprocessor in order to be able to save state on a context switch.
As to why the file format is elf32-i386 instead of elf32-k1om -
The web site you referenced referred to recompiling the kernel that came with the MPSS after possibly make a few changes in the files. You'll notice that they also copied over a configuration file for the installed version of the kernel. So they had all the files to remake the kernel exactly as it had been made.
I suspect that, in your case, either a) there was a configuration script of some sort in your source directory that picked up the architecture you were running on and caused confusion when the makefile ran or b) your makefile had no idea what k1om was. In either case, it fell back to what it believed to the the lowest common denominator i386. As I say, this is just a suspicion on my part but a careful reading of your makefiles should lead to the answer.

w_scan cross compile issue

I download the w_scan project(a small command line utility used to perform frequency scans for DVB and ATSC transmissions.) from http://wirbel.htpc-forum.de/w_scan/index_en.html. I also install gcc-arm-linux-gnueabi on my Ubuntu x86_64. I use the ./configure --host=arm-linux CC=arm-linux-gnueabi-gcc command to cross-compile, and it generates a binary file. However, I copy that file to my target board and execute that file, it shows sh: ./w_scan: No such file or directory.
I use the file command to see information of that binary file, it shows ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.31, BuildID[sha1]=0x9a584b4720fadf5eb5b77034ac85092daeb728c9, not stripped.
I found that error message stands the configuration of cross-compile doesn't correct.(reference http://ubuntuforums.org/showthread.php?t=1141792). How can I fix my configuration and correct cross-compile that project, THANKS!
./configure --host=arm-linux CC=arm-linux-gnueabi-gcc
make CFLAGS=-static
copy that binary file to my target board, it can execute normally and successfully.
And the file w_scan will shows
ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.31, BuildID[sha1]=0x67b7e9f93015607f891c0b77493d9e47059ef6a1, not stripped.

Resources