Dev/Embedded/FromScratch/UBoot

From Embeded Linux (and more) Wiki by Nathael
Revision as of 21:08, 9 January 2025 by Drizzt (talk | contribs) (→‎Flash and Use)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

U-Boot

Introduction

For most of the boards I have I'm using U-Boot as bootloader (some may be supported by other bootloaders, but I usually stick to the bootloader proposed by the board manufacturer).

"Das U-Boot" (https://www.denx.de/project/u-boot/) is one of the most used bootloader for embedded systems running Linux. It supports a wide range of hardware and many boot mechanisms (serial, ethernet, flash, USB, SD card, emmc, ...) to load the necessary images required to boot the system.
Details will be found in u-boot documentation.

Get the sources

Most of the time the official u-boot sources (from denx.de) are fine :

git clone git://git.denx.de/u-boot.git

If your board is not supported by the official u-boot sources, refer to your board documentation to get the bootloader sources. Depending on your hardware, you may need to use a specific release of u-boot. Use git checkout to get the right one.

Configure

If your hardware is supported by u-boot you should find a "<board_name>_defconfig" file in the "configs" directory at the root of the git tree.
If you do not know which one to use, you can refer to your board's documentation, or to u-boot documentation under "doc/board".
Then the configuration is made in two steps :

board_name=
compiler_prefix=
make CROSS_COMPILE=${compiler_prefix} ${board_name}_defconfig
make CROSS_COMPILE=${compiler_prefix} menuconfig

If the default configuration fits your needs the second step (menuconfig) is not required.

Compile

Once you're done with the configuration step, the compilation is made by running make from the source tree root with the "CROSS_COMPILE" variable set.

Note that for boards which require an ARM trusted firmware image it may be required to export a variable with it's path first :

platform=
target=
path_to_atf=
export BL31=${path_to_atf}/build/${platform}/debug/${target}.bin

Refer to the "ARM trusted firmware" section bellow to build this firmware image first.

And compile :

compiler_prefix=
make CROSS_COMPILE=${compiler_prefix}

The result is at the root of the source tree. The image name to use depends on your target.

How to use this image is highly dependent on your target board and SoC, so refer to the board specific information for this step !

U-Boot environment

Part of u-boot configuration includes a default environment, which holds various variables used to help loading and starting the Linux kernel.
Some of these variables have predefined meaning and other are user defined to help configure u-boot behavior.
Depending on your hardware, the default variables can be overridden from the content of a saved environment from a flash location, or from the content of a script. This helps save board specific boot configuration and select boot mechanism used to load and start the required binaries.
Whatever the mechanism used to get them, it usually boils down to loading the Linux kernel image, an optional initramfs or initrd image (which may also be included in the Linux kernel image or not required at all), and a device tree blob (dtb) if it is not included within the Linux kernel image.
The bootloader also has to provide a command line to the Linux kernel, unless the Linux kernel image has a default command line compiled in. This is done by setting the "bootargs" environment variable.
The effective boot is done then by running one of the boot commands supported by the u-boot image.
Refer to each board description for a list of board specific configurations and for example boot scripts when supported.

ARM trusted firmware (or Trusted Firmware-A)

If you are building U-Boot for an arm64/aarch64 device, you need to include the "ARM trusted firmware" (ATF) or "Trusted Firmware-A" (TF-A).

Get the sources

You can get this either from the trustedfirmware.org git repository :

git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git

These sources are also available from the arm-trusted-firmware git repository on github : https://github.com/ARM-software/arm-trusted-firmware.git
Note that both repository seems to have the same code, only some of the tags appear to be different.

Configure

There's no configuration stage for this part, though you'll need to know the "platform" name and the "target" name you want to build.

You can run "make help" to get the list of supported platform and the target names.

You can refer to the documentation for your SoC (processor) under "docs/plat" directory.

I'll indicate the right plaform and target on the pages dedicated to each board when I get my hands on them :)

Compile

To build this firmware part get to the root of the git tree and run:

platform=
target=
compiler_prefix=
make CROSS_COMPILE=${compiler_prefix} PLAT=${platform} DEBUG=1 ${target}

Set "platform" and "target" according to your needs as identified in the "Configure" section above

Flash and Use

Once your bootloader image is ready, with the eventual firmware loader if any is required, you must then put it somewhere where your processor will be able to read it.

There are many options, all depending on your hardware (the processor of course, but also the board you are using, which may have only some of the interfaces available, or specific "bootconfig" settings hardwired).
Here is a short list of the common interfaces which may be available :

  • Serial (one of the UARTs)
  • Onboard Flash (NAND, NOR or SPI Flash chips)
  • EMMC and/or SD (or µSD) Card
  • Ethernet (usually using BOOTP + TFTP)
  • USB flash drive (or USB connected Hard drive or SSD)
  • Sata drive
  • ....

Some options will require specific tools or services installed on your host, while others will require special configuration of a storage device (µSD card, USB key, ...).

I'll provide some information on this Wiki for the boards I have (on the board dedicated page), but if you want complete information about the possibilities you can have with a specific board the right place to look at is at the documentation. The board documentation may provide some information, though not necessarily all of it, so the best is to have a look at the processor documentation to know all the supported boot modes, and then at the board schematics (provided you have them) to know which ones are effectively available given the hardware configuration.

Next