|
|
Log in / Subscribe / Register

A status update for U-Boot

By Jake Edge
July 26, 2023

EOSS

The U-Boot "universal boot loader" is used extensively in the embedded-Linux world. At the 2023 Embedded Open Source Summit (EOSS), Simon Glass gave a presentation (slides, YouTube video) on the status of the project, with a focus on new features added over the last several years. He also wanted to talk about complexity in the firmware world, which he believes is increasing, and how U-Boot can help manage that complexity. The talk was something of a grab bag of ideas and changes throughout the increasingly large footprint of the project.

Background

The idea behind U-Boot is its universality; "boot anything on anything", Glass said. As a project, it has been around for 20 years or so and is currently under active development with 6000 yearly commits. U-Boot is released on a regular schedule, four times per year.

It has around three-million lines of C code, with some additional Python tools. U-Boot has a lot of similarities with the Linux kernel: it has the same code style, uses Kconfig for build-time configuration, and has some compatibility layers that allow porting Linux subsystems and drivers to U-Boot "without too much pain". U-Boot has a continuous-integration (CI) testing system that "covers a large subset of the features" of the boot loader.

U-Boot's popularity stems from its large set of features, but "it's also easy to hack"; it is not difficult to go in and add a new command or feature to the code base. It is a single-threaded application, which makes it easier to deal with because there is no locking needed; "it's not trying to be an operating system". The U-Boot developers are generally open to new ideas and features, which also helps.

Complexity

"Everything is getting more complex in this world", he said. The systems-on-chip (SoCs) that are being used in our devices have a lot more features and they need firmware to operate. The firmware needs to be packaged into an image, but that process is getting more complex as well. There are security and signing requirements for firmware these days, in order to be sure that the systems are using the correct firmware. Ten years ago, those kinds of problems were much less common.

[Simon Glass]

There is also a lot of diversity in the boot flow; systems are "now jumping through multiple projects, different binaries and so on, in order to get to an operating system". Beyond that, there is a proliferation of different device models that are all slightly distinct from each other, necessitating a different firmware image for each. It is not easy to deal with all of that diversity.

The U-Boot driver model deals with the SoC complexity "fairly well", Glass said. There can be a tree of devices, with devices being in different classes; there are relationships between the various devices "and devicetree is used to pull it all together".

One of the most complicated things to deal with is clocks; unlike in times past, the data sheets for boards do not even try to provide a clock diagram these days. But U-Boot makes a lot of that much easier with its infrastructure. "You can say 'please give me the MMC device'" and U-Boot will set up all of the clocks and pin multiplexing that is needed, turn on any power domains that are required, and return the device. "That's really really complicated to do manually", he said.

The problem of multiple, slightly different, device models has traditionally required a different boot loader for each, but U-Boot can change its configuration at run time, so that that only a single firmware image is needed. It does this using different devicetrees that can represent the various models. The devicetree for the specific model can be added into the boot image later, perhaps even as part of the manufacturing process, he said.

There are a lot of different ways to package up firmware, each person or project that does so probably has their own way. It does not seem difficult at the beginning, so some scripts are written, but eventually an entire build system evolves simply to package firmware. Binman is a tool that tries to solve this problem; it comes with U-Boot, but it is applicable to other projects, such as Zephyr, for example. It has a configuration file that describes all of the different pieces that need to be pulled into the firmware image and has support for various firmware formats so it can create the proper format for installation into the flash.

Binman solves a number of problems, he said. It allows easily changing the contents of the image, but it also provides documentation of what is present in the image. Instead of needing to decode the binary image using a variety of different tools, the binman configuration can be consulted. It also has mechanisms to fetch and build various types of tools that need to be run on bits of the firmware (e.g. for signing or vendor-specific formatting tasks).

Standard boot

The "standard boot" feature is, as its name suggests, "an attempt to make booting more standard in U-Boot". The traditional U-Boot bootm command can be used to boot a variety of images in the Flattened Image Tree (FIT) format, it will handle things like signature verification and image decompression, but it lacks a way to figure out which images should be used and where they are located on the device. That is currently done using scripts. Over the last few years, the distro_bootcmd scripts that come with U-Boot have been used to provide the proper parts and pieces for handling the boot.

Standard boot adds a higher-level interface that will allow U-Boot to fully see what boot devices and images are available on the device; it can then offer a menu to users to choose between the options. A bootdev is a layer on top of a storage device (e.g. MMC) that can enumerate the bootable images it contains. A bootmeth can then enumerate the available bootflow files that describe a specific boot process for the system. The "distro" bootmeth looks through the filesystems that were discovered by the bootdevs for files named extlinux/extlinux.conf. Those files describe the bootflow for the particular distribution, such as Android, Fedora, Ubuntu, Chrome OS, and so on. It is a straightforward model, but can be a bit hard to wrap one's head around, he said, and U-Boot is still in the process of converting to it.

U-Boot has long had UEFI support and can boot distributions, such as Fedora and Ubuntu, directly via UEFI. It also supports UEFI Secure Boot and can handle things like using the Trusted Platform Module (TPM) for measurement and attestation of the boot process. U-Boot can also be run as an EFI application directly if desired.

There is an alternative to UEFI these days, though. Verified Boot for Embedded (VBE) is an effort to answer the question: "if we are not going to use UEFI, what would it look like?" He did not want to get into the details of VBE and recommended his talk from last year's Open Source Firmware Conference (OSFC) for more information. It is based on existing standards, such as the FIT format. Instead of having a bunch of callbacks from the boot image to U-Boot, as is done in UEFI Secure Boot, it provides the image with all that it needs up front, which is a simpler approach, he thinks.

The U-Boot project has moved to using Sphinx for its documentation over the past few years; there was an earlier U-Boot manual, but it "just sort of died" along the way. The good thing about the new documentation is that it lives in the source tree, so a patch that adds a new feature or command can contain the documentation (and, hopefully, tests) as well. Most of the existing documentation has been converted to reStructuredText at this point, but there are still commands and features that lack documentation; the hope is to close that gap before too long.

The testing and CI system for U-Boot is another area that has "expanded considerably in the last few years". Glass noted that there had been a Zephyr talk at EOSS about emulated devices for testing; U-Boot uses those as well, so you can test U-Boot from an emulated SPI flash, for example, on a Linux workstation. It allows writing all sorts of tests that can be run without the hardware; the emulators can be altered to make the "hardware" do things that need to be checked. Now, if someone sends a patch without a test, they can be asked to provide one and it is not a huge burden to do so.

Devicetree and beyond

U-Boot adopted devicetree in 2011 at roughly the same time that Linux did, which is a bit of problem because the bindings (properties, nodes, etc.) are different between them. Those differences are being resolved over time. Another problem is that U-Boot has not been able to upstream its schema requirements to the kernel, though that is changing as well. The idea is that U-Boot can get its devicetree from Linux and, as long as it has all of the drivers for the hardware it needs from the devicetree, it can simply use it.

While U-Boot has used Kconfig at least as long as Glass has been working on it (nearly ten years), it still had a lot of #define configuration statements scattered around in header files, but that has all been cleaned up as of the beginning of the year. There is now a text file that describes the configuration, which means that there is a path toward having no board-specific config.h files at all; a board can be fully specified in the configuration text file.

The project has added link-time optimization (LTO) as well. "It makes your board take four times as long to build, but it is 5% smaller." It is generally a win, so it is turned on by default for most Arm boards. In addition, the events feature provides a way to spy on things like device creation; it is an alternative to using weak functions, which he is not a big fan of because it is hard to determine where they are being called. An event gets published and other locations can indicate their interest in particular events, then process them when they occur; the spies can be easily listed using a tool, so they have more visibility.

Something that is going on behind the scenes is an effort to allow different parts of the firmware to hand off configuration data and other information to the next stage in the firmware. Currently, there can be multiple stages (including the verifying program loader (VPL), secondary program loader (SPL), trusted execution environment or trusted firmware, and U-Boot) that are separate projects, each with its own configuration mechanism. The Firmware Handoff specification is for a "simple, tagged data structure" that can be passed between these components.

There have "been quite a few changes" in the networking support for U-Boot, starting with the addition of TCP/IP; that means Wget can be used, "which is kind of handy". TFTP support has been around for a while, but it is much more limited. There is also IPv6 support now and a new PHY API. There are currently ongoing discussions about whether U-Boot should switch to using the lightweight TCP/IP stack, lwIP, or whether it should continue with its own implementation.

There is now support for 21 different RISC-V boards in U-Boot. Booting distributions on x86 is now just a few pending patches away from being fully supported. Using U-Boot as a coreboot payload on x86 has been enhanced. Coreboot can be used to do the initial boot of the system, setting up the hardware, including the ACPI tables, then jump into U-Boot to boot the operating system. That process is now "a little more polished".

Tracing can be used in U-Boot to track down boot-time bottlenecks. The tracer will record function entry and exit into a memory buffer that can be exported to another system for analysis. Tracing has been part of U-Boot for some time, but it was recently updated to use the trace-cmd interface.

He had mentioned that U-Boot is single-threaded, which makes it easier to work with, but it can be annoying too. If you do a USB scan, for example, you have to wait while the scan is being done, timeouts are being reached for ports, and so on; it can take several seconds if there are a lot of ports. It would be nice to have a way to start the scan process and to do other things, which is what the cyclic subsystem could help to provide.

Whenever U-Boot is idle, it jumps into the cyclic scheduler. The cyclic subsystem has been used to reset the watchdog timer for many years, but now it is available to other users in the system. He has a number of ideas for how it could be used (including for USB scanning), but looks forward to seeing what others come up with as well.

A new, experimental feature is to add a GUI of sorts using expo menus. These menus are a set of screens, called scenes, that the user can navigate using the keyboard to set or change various parameters. They look and act much like simplified x86 BIOS menus.

Glass did a fairly fast-moving and somewhat hard-to-follow series of demos that were meant to show some of the different features he had mentioned in the talk. He started by showing the standard boot process in QEMU and then ran binman to display. the contents of the boot image that he used. He also demonstrated how binman can be used to go out and fetch a missing tool (e.g. fiptool) so that it can be used to build the firmware image. Beyond that, he pushed a branch to GitLab and briefly poked around the CI system there, created a flame graph from the tracing output, and showed the expo GUI.

After that, he took a few audience questions; one of those was about priority in the standard boot. Is there a way to specify that certain bootdevs (or types of storage, such as removable or not) should have priority over others? Glass said that each bootdev type does have a priority that can be specified, but that there is no distinction based on whether the media is removable or not, so that would need to be added. The boot order can also be specified by the order that devices appear in an environment variable.

[I would like to thank LWN's travel sponsor, the Linux Foundation, for assisting with my travel to Prague.]


Index entries for this article
ConferenceEmbedded Open Source Summit/2023


to post comments


Copyright © 2023, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds