How to boot bare board binary from U-Boot? - u-boot

How can we boot independent bare board binary(not standalone binary which runs using U-Boot environment and not linux kernel) from U-Boot. My requirement is to reinitialize the board and drivers using my binary...
I can replace the U-Boot in the boot medium(here NOR Flash) with my binary but my requirement is to not removing the U-boot from NOR flash and I should load my binary from LAN network using "tftp" command.
Thanks and Regards,
Veerendranath

How to boot bare board binary from U-Boot?
Use U-Boot's go command to execute any kind of standalone program.
How can we boot independent bare board binary(not standalone binary which runs using U-Boot environment and not linux kernel) from U-Boot.
Use U-Boot's go command to execute any kind of standalone program.
... I should load my binary from LAN network using "tftp" command.
Use U-Boot's tftpboot and go commands to execute any kind of standalone program. (The abbreviated tftp command has been deprecated now that there's also a tftpput command.)
Here problem is when I use go command my program has to use U-Boot service functions(I mean standalone binaries will run in U-Boot environment)...
You're misinformed, there is no requirement that you have to "use U-Boot service functions".
Build your standalone program independently of U-Boot, and it will execute completely independent of U-Boot.
But I can't boot using bootm or any other boot commands provided by U-Boot as my binary is not in kernel format.
There is no "kernel format"; that's why U-Boot uses the mkimage wrapper to identify binaries.
The bootm command is designed specifically for the booting requirements of OSes such as the Linux kernel (e.g. a buffer containing the command line parameters) by specifying the characteristics of the binary.
Use U-Boot's go command to execute any kind of simple, standalone program.
If you have issues executing your binary when using the go command, then the problem lies with your program, e.g. taking control of the processor and initializing its C environment.
ADDENDUM
When I use the term standalone program, I'm referring to the generic definition (aka bare-metal), and not the U-Boot-specific definition related to its examples/ directory.
FWIW I have used the go command for both kinds of "standalone" programs.
U-Boot describes its "standalone" as
* "Standalone Programs" are directly runnable in the environment
* provided by U-Boot; it is expected that (if they behave
* well) you can continue to work in U-Boot after return from
* the Standalone Program.
Note that the use of the U-Boot environment is optional.
A standalone program is not required to use the U-Boot environment, especially if there is no intention of returning back to U-Boot.
There is nothing in U-Boot to detect or restrict the behavior of a standalone program.
If you cannot get your standalone program to work with the go command, then the problem lies with your program, and not the go command.
The go command merely transfers control (i.e. a branch instruction to the specified memory location), and places no restrictions or requirements whatsoever on that code (other than what is sensible for operation of the system).
Use an in-circuit emulator (ICE) or JTAG debugger to resolve problems with your code, especially when your program does not use the existing stack.
ADDENDUM 2
Instead of the ambiguous go command, the mkimage wrapper does provide for the standalone image-type for use with the bootm command.
See Creating a bare metal boot image, but don't expect different results from a go command.
The advantages of using a wrapper and bootm over go is that the downloaded image (a uImage file) can be:
identified/verified with the iminfo command,
compressed (e.g. gzip, bzip2, lzo) or uncompressed.

You can create the boot.bin with fsbl, bitstream, uboot.elf and you applications. Then flash in the QSPI flash and choose to boot from it.
Or you can boot from TFTP. Here you need to create the boot.bin just with fsb, bitstream, and uboot.elf. You need the change the uboot header file to force it boot from tftp like tftpboot 0x0 hello.elf. Once booted it will grab the elf/bin file with tftp and boot the board with bootelf or go command.
The same you can boot from SD card if there is one.

Related

How to run an i386 .so library on an armhf system?

I need to implement a system with a third party device using a Raspberry Pi.
The device is connected using USB, and the manufacturer has provided a few software implementation demos, and the driver library includes a C++ header file and a C shared object file compiled for i386.
I need to be able to run this driver library on the RPi. My idea is to build a C++ program I can use to get the data from the device, compile for i386, and run it with qemu-i386. I have tried to execute this idea, but have run into some problems relating to the linking, like the executable looking for ld-linux.so.2, which my RPi doesn't have.
How can I get this to work?
It's a bad idea to run it for QEMU, instead install box86, link, it'll automatically take over when it detects a 32bit x86 executable and should work great for your use case

How to create bootable application image (efi)?

I trying to boot an elf microkernel in an UEFI environment. So i compiled a minimal boot loader and created an ESP image. This works fine if I boot via an HDD but I want to direct boot it via the qemu -kernel option (This is some special requirement as I am working with AMD SEV). This doesn't work.
I can boot my kernel like this with grub if I use grub mkimage with a fat image included i.e. like this:
mcopy -i "${basedir}/disk.fat" -- "${basedir}/kernel" ::kernel
mcopy -i "${basedir}/disk.fat" -- "${basedir}/module" ::module
grub-mkimage -O x86_64-efi
-c "${basedir}/grub-bootstrap.cfg"
-m "${basedir}/disk.fat"
-o "${basedir}/grub.efi"
But the goal for my system is minimalism and security hence the microkernel, so grub and it's vulnerabilities is out of question.
So my question is:
How to create a bootable application image similar to grub-mkimage?
I have read about efi stub boot but couldn't really figure out how to build an efi stub image.
Normally I am a bare metal embedded programmer, so the whole uefi boot thing is a bit weird to me. I am glad for any tips or recommendations. Also I figured stack overflow might not be the best place for such low level questions, can you maybe recommend other forums?
I want to direct boot it via the qemu -kernel option
Why? It's a qemu-specific hack that doesn't exist on anything else (including any real computer). By using this hack the only thing you're doing is failing to test anything you'd normally use to boot (and therefore failing to test anything that actually matters).
(This is some special requirement as I am working with AMD SEV)
That doesn't make any sense (it's a little bit like saying "I have a banana in my ear because I'm trying to learn how to play piano").
AMD's SEV is a set of extensions intended to enhance the security of virtual machines that has nothing at all to do with how you boot (or whether you boot from BIOS or UEFI or a qemu-specific hack).
I am glad for any tips or recommendations.
My recommendation is to stop using GRUB specific (multi-boot), Qemu specific (-kernel) and Linux/Unix specific (elf) tools and actually try to use UEFI. This will require you to write your own boot loader using (Microsoft's) PE32+ file format that uses UEFI's services itself. Note that GNU's tools (their "Gnu-EFI" stuff for GCC) is relatively awful (it puts a PE32+ wrapper around an ELF file and does run-time patching to make the resulting Franken-monster work); and there are much better alternatives now (e.g. the Clang/LLVM/lld toolchain).
If you care about security, then it'll also involve learning about UEFI SecureBoot (and key management, and digital signatures). If you care about secure virtual machines I'd also recommend learning about the SKINIT instruction from AMD"s manual (used to create a dynamic root of trust after boot); but don't forget that this is AMD specific and won't work on any Intel CPU, and is mostly obsolete (the "trusted measurement" stuff from BIOS and TPM was mostly superseded by SecureBoot anyway), and (even on Intel CPUs) if you're only the guest then the hyper-visor can emulate it in any way it wants (and it won't guarantee anything is secure).
Finally; note that booting a micro-kernel directly doesn't make much sense either. There's no device drivers in a micro-kernel; so after booting a micro-kernel you end up with a "can't start any device drivers because there are no device drivers" problem. Instead you need to load many files (e.g. maybe an initial RAM disk), then (e.g.) start some kind of "boot log handler" (to display error messages, etc); then find and start the kernel, then start other processes (e.g. "device manager" to detect devices and drivers; "VFS layer" to handle file systems and file IO; etc). For the whole thing; starting the kernel is just one relatively insignificant small step (not much more than starting a global shared library that provides multi-tasking) buried among a significantly larger amount of code that does all the work.
Sadly; booting a monolithic kernel directly can make sense because it can contain all the drivers (or at least, has enough built into the kernel's executable file to handle an initial RAM disk if it's "modular monolithic" with dynamically loaded drivers); and this "monolithic with stuff that doesn't belong in any micro-kernel" idea is what most beginner tutorials assume.

How is Zircon kernel image linked? (where is link.ld script)

I'm reading the Zircon source code: https://fuchsia.googlesource.com/fuchsia/+/master/ and I'm trying to find how the kernel image is linked. That is, where is the start function placed?
For example, on raspberry pi, the kernel.img start function is placed at 0x80000 with a link script like here: https://github.com/bztsrc/raspi3-tutorial/blob/master/01_bareminimum/link.ld
There is the boards directory: https://fuchsia.googlesource.com/fuchsia/+/master/boards/ which has some dependencies for some boards. It adds some needed drivers. However, I couldn't find anywhere where the linking occurs for each board.
What if I want to support a new board? Suppose I want to port Zircon to raspberry pi, so I need to make the start.S, specifically the start function on it, start at 0x80000. How would I instruct the Zircon build system to do it?
There are a handful of layers to understand, some of which are a little different.
Here's the linker script you may be looking for, but it doesn't tell the whole story: https://cs.opensource.google/fuchsia/fuchsia/+/master:zircon/kernel/phys/zbi_executable.gni
Kernel images included in ZBI's are generated around here, depending on configuration:
https://cs.opensource.google/fuchsia/fuchsia/+/master:zircon/kernel/BUILD.gn;l=465
There are also boot-shims, which are used to bridge various worlds to ZBI, some for arm64 are here: https://cs.opensource.google/fuchsia/fuchsia/+/master:zircon/kernel/target/arm64/boot-shim/
These also have the kinds of build parameters you may be looking for:
https://cs.opensource.google/fuchsia/fuchsia/+/master:zircon/kernel/target/arm64/boot-shim/BUILD.gn;l=37
Multiboot is common in the Linux world, and this shim for x64 handles exactly that:
https://cs.opensource.google/fuchsia/fuchsia/+/master:zircon/kernel/target/pc/multiboot/
An example boot shim configuration with minimal dtb interaction is here: https://cs.opensource.google/fuchsia/fuchsia/+/master:zircon/kernel/target/arm64/board/msm8998/boot-shim-config.h;bpv=0

Zynq Qspi Booting

I'm using Arm DS-5 and Xilinx SDK for developing programs on Zynq board.
I'm trying to boot Zynq 702 board from Qspi Flash.
What I've done so far is generating FSBL project from Xilinx SDK, and combining it with my application using Bootgen tool in SDK, then program it into the flash.
There are several questions in my mind.
DS-5 produces an .axf file, Bootgen requires an .elf file. Can I use
the .axf file by just changing its extension to .elf or do I require
some more steps?
Is there a tool that shows the inner structure of an .axf file?
Showing what is where?
And how can I debug if I managed to boot from QSPI. For example I want to debug my application from the beginning of FSBL, is it possible? Because in Qspi Boot, When I power on the board, my application would start running and when I connect with JTAG, it would be in somewhere in my application.
An AXF might have some extra ARM-toolchain magic in it (I'm not sure off-hand), but at heart it's an ELF file - the ARM toolchain provides fromelf for poking around inside them, but other tools like readelf and objdump also work.
I'm not familiar with the Zynq platform so I don't know any specific debugger tricks, but a general one is just to put an infinite loop at the start of your code (possibly using volatile or inline asm trickery if necessary to prevent optimisation) - once the debugger's connected and broken into it, you just move the PC past the loop and continue.
You can totally halt QSPI-booted Zynq via JTAG and do whatever you want with it. However, there are some quirks. Sometimes Zynq goes into some kind of lockup, and JTAG doesn't work at all, and you need to power-cycle before retrying. Some not-so-well-written peripherial might die after starting software over JTAG, so you might need to re-load bitstream first. And there are some Vivado-related bugs (like the one where you cannot re-flash the board unless you downgrade to 2017.2 or change MIO2-6 pulls or patch the FSBL) but i'm not sure if they apply in your case.

OPENOCD, flash program to ARM Cortex M0 (JTAG)

I'm new on OpenOCD, has anyone attempted to use Olimex OpenOCD to actually flash program hex file (from Kiel say) into ARM CORTEX M0 (generic).
What do I need to setup script file to take each word of the hex file to performs mww (memory write word) within the MCU flash?, can anyone provide an example. I use python.
I open for suggestion.
I use Window PC.
All Cortex M0 that I know of have no JTAG, but only SWD support. SWD is not yet available in OpenOCD - it is still in development.
Another note: The method for writing the flash memory is specific for each vendor/chip.
Sure, what platform in particular? some googling will find the exact sequence. flash unlock, erase, program, etc.
Section 6 of this page for example.
http://pygmy.utoh.org/riscy/cortex/led-lpc17xx.html
I am trying to figure out what board I did it on but those were pretty much the commands I followed and it worked just fine. It may have been the leaflabs maple mini. The steps are the same. To avoid the steps or scripting it, etc. what I ended up doing was writing a few lines of bootloader that said if ram+0 = 0x12345678, and ram+4 = 0x87654321 then branch to ram+8 else infinite loop. then it was trivial to use the jtag to load a program into ram with the two words and an entry point at 0x08 bytes into ram, press reset and run the program. On a cold power up it just hits the infinite loop. I spend my day on a bigger arm based system loading everything into ram using jtag so it made it quite comfortable. You could just script it in openocd and simply type the openocd command have the flash load happen.
Update for people stopping by...
You do not have to use mww, if you're just trying to flash-program (eg. upload your own code) to your microcontroller.
Some time ago, OpenOCD got a ("built-in") convenience-script, that you can use for programming, this "command" is called "program".
Here's an example from the documentation on the "program" command:
openocd -f interface/ftdi/jtag-lock-pick_tiny_2.cfg -f board/stm32f3discovery.cfg -c "program filename.elf verify reset"
-Replace "stm32f3discovery" by your board. If you use a different adapter, replace the interface with the appropriate configuration file.

Resources