Unlocking Modern Storage: U-Boot Adds LUKSv2 Support

We’re excited to announce that U-Boot concept has merged support for unlocking LUKSv2 encrypted partitions! This is a significant enhancement to U-Boot’s security capabilities, allowing it to handle the encryption standard used today by most current Linux distributions.

This 16-patch series (and a small follow-up) bring U-Boot up to speed with modern disk encryption, building on the existing luks unlock command.

Why LUKSv2?

While LUKSv1 was added initially, it was with the intention of taking this next step. LUKSv2 is the modern standard, offering superior security. The two key features U-Boot now supports from LUKSv2 are:

  1. Argon2id Key Derivation: LUKSv2 defaults to using Argon2id, the winner of the Password Hashing Competition. Unlike LUKSv1’s PBKDF2, Argon2id is a memory-hard function designed to be highly resistant to brute-force attacks using GPUs and ASICs. This series introduces the Argon2 library to U-Boot to handle this.
  2. XTS Cipher Mode: Support for the AES-XTS cipher mode (via mbedtls) has been added. XTS is the modern standard for disk encryption, providing stronger security guarantees than the older CBC mode.

The Implementation: A JSON-to-FDT Converter

One of the most interesting challenges in this series was handling the LUKSv2 metadata format. Unlike LUKSv1’s binary header, LUKSv2 stores its complex, hierarchical metadata as a JSON object.

As noted in the cover letter:

“One interesting part of this series is a converter from JSON to FDT, so that U-Boot’s existing ofnode interface can be used to access the hierarchical data in JSON text. This obviously results in quite a bit of new code, but it is more robust than trying to parse the text directly using strstr(), etc.”

This is the core of the new implementation. Instead of writing a new, complex JSON parser from scratch, a new function, json_to_fdt(), was created. This function parses the JSON text and converts it on-the-fly into a Flattened Device Tree (FDT) blob in memory.

From there, the LUKSv2 code can use U-Boot’s familiar and robust ofnode API (ofnode_find_subnode(), ofnode_read_string(), etc.) to navigate the metadata and retrieve keyslots, digests, and segment information. This approach is not only more reliable but also fits better within the existing U-Boot architecture.

How It Works

For the command interface, not much has changed. The existing luks unlock command just grows some new features:

  • It automatically detects whether the partition is LUKSv1 or LUKSv2.
  • If it’s LUKSv2, it will parse the JSON metadata.
  • If the keyslot uses Argon2id, it will use the new Argon2 library to derive the key.
  • If the partition uses XTS, it will use the newly enabled mbedtls functions to decrypt it.

Once unlocked, the encrypted partition is mapped as a blkmap device (e.g., blkmap 0), which you can then read from using standard commands like ext4load, fatload, or ls.

This work, along with the necessary documentation and test updates, makes U-Boot ready to boot from modern, secure, full-disk-encrypted systems.




Unlocking Disks Earlier: Basic LUKS1 Support Arrives in U-Boot

A new 24-patch series in Concept that introduces basic support for unlocking LUKS1 encrypted partitions directly within U-Boot. This is a foundational step toward a more integrated and user-friendly full-disk encryption (FDE) experience.

🤔 The Problem with “Late” Unlocking

Traditionally, FDE on Linux systems is handled late in the boot process. U-Boot loads a kernel and an initial ramdisk (initramfs), and it’s the initramfs’s job to prompt the user for a passphrase and unlock the main root filesystem.

This common approach works, but it has several drawbacks:

  • Firmware is blind: U-Boot has no way of knowing if the boot will succeed until long after it has handed off control.
  • Confusing user experience: The passphrase prompt appears late in the boot sequence, sometimes after the vendor logo has disappeared.
  • No integrated UI: It’s not possible to create a single, polished firmware UI that handles both boot selection and disk decryption.
  • Inflexible for automation: In VM environments where a key might be known in advance, there’s no way for the firmware to use it, so the ramdisk must handle this through attestation, etc.
  • Ramdisk is required: You can’t boot from an encrypted disk unless you also use a ramdisk to perform the unlock.

💡 What’s New: The luks Command

This patch series takes a small step to improve this by bringing decryption capabilities into U-Boot itself. The new feature set is centered around the luks command, which allows U-Boot to interact with LUKS-encrypted partitions.

The command introduces three main subcommands:

  1. luks detect: Checks if a given partition is a valid LUKS device.
  2. luks info: Parses and displays the LUKS header metadata. This works for both LUKS1 and LUKS2 partitions, thanks to a new simple JSON parser included in the series for handling the LUKS2 header.
  3. luks unlock: unlocks a LUKS1 partition using a provided passphrase.

Here’s a look at it in action:

=> luks detect mmc 1:2
LUKS1 encrypted partition detected

=> luks info mmc 1:2
Version:         1
Cipher name:     aes
Cipher mode:     cbc-essiv:sha256
Hash spec:       sha256
Payload offset:  4096 sectors
Key bytes:       32

=> luks unlock mmc 1:2 mysecretpassphrase
Unlocked LUKS partition as blkmap device 'luks-mmc-1:2'
=>

🔓 Accessing Decrypted Data via blkmap

Once a partition is unlocked, how do you access the data? The luks unlock command integrates with U-Boot’s blkmap subsystem.

When a partition is successfully unlocked, a new virtual blkmap device is created. This device provides read-only access to the decrypted data on-the-fly.

This means you can now use standard U-Boot commands to read files directly from the encrypted partition, just as if it were a normal, unencrypted disk:

=> ls blkmap 0 /
          ./
          ../
          lost+found/
2481008   vmlinuz-6.8.0-53-generic
1616      initrd.img-6.8.0-53-generic

=> ext4load blkmap 0 ${kernel_addr_r} /vmlinuz-6.8.0-53-generic
2481008 bytes read in 64 ms (37.0 MiB/s)
=>

This simple feature allows U-Boot to load a kernel, read a configuration file, or access any other data from an encrypted volume before booting.

🛠️ Under the Hood: What Made This Possible

There is quite a bit of foundational work included in this series:

  • Crypto: The mbedtls library in U-Boot was enhanced to enable PKCS#5 (PBKDF2) functions, which are essential for deriving keys from passphrases in LUKS. A fix for AES-192 and AES-256 key-size handling was also included.
  • blkmap Enhancement: The blkmap driver was extended with a new blkmap_map_crypt() function to handle the on-the-fly decryption.
  • Testing: A large portion of the series is dedicated to building solid testing infrastructure. This includes updates to the Docker image, CI configuration and new Python test helpers (fs_helper.py) to create, encrypt, and test against real LUKS1 and LUKS2 disk images.

This series lays the groundwork for a more secure and streamlined boot process. While full LUKS2 unlock support and read-write access are topics for another day, this is a step forward.





Pass a boot command to QEMU!

The build-qemu script provides lots of useful features and is an easy way to run U-Boot under QEMU with an OS, with or without video, etc. Now in Concept it is possible to pass a boot command!

The -b/–bootcmd option creates a special ‘file’ within QEMU that contains the requested command. Then U-Boot uses an event in main.c to check for that file and read it. The command is then executed instead of the autoboot command. In effect, it provides a way to control what U-Boot does when it starts up.

Possible uses may include setting the bootmeth order to boot using extlinux instead of EFI.

Note that this does not affect the preboot command.

The main patch is the addition of a new EVT_BOOTCMD event which is emitted in main_loop() before starting the main CLI loop. Under the hood, QEMU provides the information in its internal filesystem, the the opt/u-boot/bootcmd file. You can see this using the ‘qfw’ command:

$ ./scripts/build-qemu -a x86 -rs -b 'echo hi'

U-Boot Concept SPL 2025.10
Trying to boot from SPI


U-Boot Concept 2025.10

CPU:   QEMU Virtual CPU version 2.5+
DRAM:  512 MiB
Core:  19 devices, 12 uclasses, devicetree: separate
Loading Environment from FAT... ** Bad device specification virtio 0 **
Model: QEMU x86 (Q35)
Net:   eth0: virtio-net#0

Hit any key to stop autoboot:  0 
hi
=> qfw list
    Addr     Size Sel Name
-------- -------- --- ------------
       0        0  20 bios-geometry                                           
       0        0  21 bootorder                                               
1ec21000       14  22 etc/acpi/rsdp                                           
1ec21040    20000  23 etc/acpi/tables                                         
       0        4  24 etc/boot-fail-wait                                      
       0       28  25 etc/e820                                                
       0       18  26 etc/smbios/smbios-anchor                                
       0      13b  27 etc/smbios/smbios-tables                                
       0        1  28 etc/smi/features-ok                                     
       0        8  29 etc/smi/requested-features                              
       0        8  2a etc/smi/supported-features                              
       0        6  2b etc/system-states                                       
       0     1000  2c etc/table-loader                                        
       0        0  2d etc/tpm/log                                             
       0     2400  2e genroms/kvmvapic.bin                                    
       0        7  2f opt/u-boot/bootcmd                                      
=> 

For now this option is only supported on x86, but ARM support should land in the next few weeks.

The build-efi script also supports this option for the app, but it is implemented in a completely different way. It creates an environment file on the FAT filesystem which U-Boot can read when it starts up. A later series provides this feature which is has also landed in Concept.

The ability to pass information from the host is a useful feature in QEMU. Keep it in mind if you are working in an emulation environment!




ACPI Firmware Performance Data Table

U-Boot Concept now has preliminary support for the ACPI Firmware Performance Data Table (FPDT). It is included in the ‘bootstage and script enhancement’ series. The OS can look at this table to figure out how long the firmware took to boot.

Only the ‘basic boot’ record is supported. It contains the following fields:

  • reset_end – Timestamp for the end of reset. This is set to the timestamp when U-Boot starts, or strictly speaking, when it sets up bootstage.
  • loader_start – Timestamp for when U-Boot starts loading the OS (not supported)
  • loader_exec – Timestamp for when U-Boot starts OS execution. This presupposes the EFI loader, i.e. starting the OS does not actually mean that U-Boot is finished. For now this is not supported.
  • ebs_entry – Timestamp for when the OS (or EFI app) calls exit-boot-services (not supported)
  • ebs_exit – Timestamp for when U-Boot completes the exit-boot-services call (not supported)

All timestamps are 64-bit values in microseconds with 0 assumes to be the end of the reset signal.

As you can see from the above, most of the fields are not currently filled in. Further work will be needed to plumb this into U-Boot’s EFI loader. As with the BGRT (blog link) the FPDT is added to the ACPI tables provided by QEMU, when running under emulation.




A Cursor Comes to the U-Boot Console

For a long time, editing commands in the U-Boot video console has been an exercise in memory. Without a visible cursor, it was often difficult to know your exact position in a long command line. A new 41-patch series in Concept changes that by introducing comprehensive cursor support for U-Boot’s video consoles.

This update brings a familiar (but so far non-blinking!) cursor to the command line, making editing commands a much more intuitive process.

How It Works

The new cursor functionality is designed to be efficient and visually clean.

  • Idle Display: The cursor is only drawn when U-Boot is idle and waiting for input. As soon as you begin typing or a command is executed, the cursor is hidden.
  • Save and Restore: To prevent visual artifacts, the video driver now saves the framebuffer pixels that are underneath the cursor’s position before it is drawn. When the cursor needs to be hidden, these saved pixels are restored, ensuring that the original display content is perfectly preserved.
  • Broad Support: This functionality is not limited to one type of console. The new cursor is supported on both the standard bitmap-font console (console_normal) and the more advanced console_truetype.

Related Improvements

This series goes beyond just adding a cursor and includes several related enhancements that improve the overall console experience:

  • Truetype Console Upgrades: The truetype console receives two major improvements. First, it can now render standard bitmap fonts, making it more versatile. Second, a long-standing issue has been fixed where using arrow keys to edit commands would corrupt the displayed text. Command-line editing with truetype fonts is now much more reliable.
  • Expo on Standard Consoles: The expo toolkit’s line-editing feature, previously dependent on the truetype console, now works with the standard bitmap-font console as well. This is made possible by the new console state-tracking implemented for the cursor.
  • Thoroughly Tested: The series includes a new set of tests specifically for the cursor functionality, verifying backspace behavior and ensuring there are no visual artifacts left behind after editing.

This work represents a significant quality-of-life improvement for anyone who works regularly with the U-Boot command line without a serial UART. To enable it on your board, simply add CONFIG_CURSOR=y to your configuration.




Mouse Support Comes to U-Boot

We’re excited to announce a new patch series that brings mouse support to U-Boot! This long-awaited feature resurrects some old code that was originally developed for Nuklear integration and provides a comprehensive mouse input framework.

What’s New

The 17-patch series (1,374 lines added across 44 files) introduces a simple mouse subsystem including:

  • Mouse Uclass: A new device model class for mouse devices
  • Multiple Driver Support:
  • Sandbox mouse driver for development and testing
  • USB mouse driver for x86 platforms
  • EFI mouse driver for EFI applications
  • Command Interface: New mouse command to display mouse input
  • Script Integration: Updated build-efi and build-qemu scripts with mouse support

Key Features

Universal Mouse Support

The new mouse uclass provides a consistent interface across different platforms and hardware configurations. Whether you’re running U-Boot on real hardware, in QEMU, or as an EFI application, mouse support is now either available or can be plumbed in.

USB Mouse Integration

For x86 platforms, the USB mouse driver enables standard USB mice to work with U-Boot after running usb start. This is particularly useful for interactive applications and debugging.

EFI Simple Pointer Protocol

The EFI mouse driver implements the EFI Simple Pointer Protocol, making mouse support available when U-Boot runs as an EFI application on real hardware.

Testing Framework

Comprehensive testing support includes unit tests for the mouse uclass and integration with the sandbox environment for development.

Current Status

The mouse support is functional across multiple platforms:

  • ✅ X86 QEMU (after usb start)
  • ✅ Real hardware with EFI
  • ✅ Sandbox environment for development

There are are a few limitations:

  • ARM QEMU mouse support needs refinement
  • USB mouse initialization timeout (though functionality works)

Looking Forward

This mouse support lays the groundwork for more interactive U-Boot applications and improved user interfaces. The framework is designed to be extensible, allowing for future enhancements and additional mouse driver implementations.





Taming Verbose Commands: Introducing the U-Boot Console Pager

Have you ever run the help or env print command and watched a torrent of text scroll past, faster than you could read it? We’ve all been there. Important information disappears off the top of the screen before we have a chance to digest it.

Well, those days are over! Thanks to a new patch series, U-Boot Concept now includes a console pager, a simple but highly effective feature that makes managing long command outputs a breeze.

What is the Pager?

At its core, the pager does one thing very well: it pauses output once your screen is full. When you run a command that generates a lot of text, the pager will stop after a certain number of lines and display a prompt:

: Press SPACE to continue

This gives you all the time you need to read the output. Once you’re ready, just press the SPACE bar, and U-Boot will display the next screenful of text. It’s an intuitive and familiar experience for anyone who has used tools like less or more in a Linux environment.

How to Use and Configure It

The pager is enabled with the CONFIG_CONSOLE_PAGER option. Once enabled, U-Boot uses a smart system to determine the page size (i.e., how many lines to show before pausing). Here’s the order of priority:

  1. The pager Environment Variable: You have full control. You can set the number of lines (in hexadecimal) yourself (‘setenv pager 1e’). Setting it to 0 disables the pager.
  2. Automatic Device Detection: If the pager variable isn’t set, U-Boot tries to be clever.

    • If you’re using a video console (vidconsole), it will automatically use the number of rows your display supports.
    • If you’re on a serial console, U-Boot can query the terminal to get its dimensions. This is enabled by CONFIG_SERIAL_TERM_PRESENT.

  3. Default Value: If all else fails, it falls back to a sensible default defined by CONFIG_CONSOLE_PAGER_LINES.

Under the Hood: A Foundation of Quality-of-Life Improvements

Introducing the pager wasn’t just a single patch. This feature was built on a solid foundation of refactoring and improvements throughout the console and serial subsystems.

One of the key preparatory steps was to generalize terminal size detection. Previously, the logic to query a terminal’s rows and columns was tucked away in the EFI loader. This code has now been moved into the generic serial uclass, making it available to any part of U-Boot. To improve performance, the terminal dimensions are cached, so U-Boot only has to ask once.

Additionally, new helper functions were introduced to determine if the console is actually connected to an interactive terminal (serial_is_tty()) or if a video display is visible. This is particularly important for environments like sandbox, where U-Boot’s output might be redirected to a file. In those cases, the pager intelligently disables itself to prevent scripts from hanging.

A Boon for Testers and Developers

Speaking of automated testing, the pager could potentially cause tests to hang while waiting for user input. To solve this, two new command-line flags have been added to the sandbox environment:

  • -P: Bypasses the pager completely.
  • -A: Assumes no terminal is present, which disables the terminal-size query.

Our Python test suite has already been updated to use these flags, ensuring that automated testing remains smooth and reliable.

Conclusion

The console pager is a nice quality-of-life improvement that makes the U-Boot command line more user-friendly. It’s a small change that will have a big impact on daily development and debugging workflows, particularly on devices without a serial console. This work, along with the thoughtful refactoring that supports it, is a great example of the continuous effort to polish and improve the U-Boot user experience.

So go ahead, enable CONFIG_CONSOLE_PAGER, and enjoy a more civilized console experience!




Streamlining Your Patch Workflow with Patman Series Management

Managing patch series can be one of the most time-consuming aspects of contributing to large open-source projects like U-Boot and Linux. While patman has long been a powerful tool for creating, checking, and sending patches, the relatively new patman series feature takes workflow management to the next level by providing lifecycle management for series, with Patchwork integration.

What is ‘patman series’?

The patman series feature (available via patman s or patman ser for brevity) is a database-backed, series-management system that tracks your patch series from initial creation through upstream acceptance. Unlike traditional patch workflows where you manually track versions, reviews, and status across multiple tools, patman series provides a unified interface that integrates directly with Patchwork to automate much of this tedious bookkeeping.

Key Benefits

Automated Series Tracking: Once you add a series to patman’s database, it automatically tracks versions, maintains links to Patchwork, and monitors upstream progress.

Seamless Version Management: Creating v2, v3, etc. of your series is as simple as patman series inc, which automatically creates new branches and updates the database.

Patchwork Integration: Patman automatically discovers your series on Patchwork after sending, tracks review comments, and can gather review tags back into your commits.

Branch Organization: The system encourages a clean branching strategy where each series version gets its own branch, making it easy to maintain multiple versions simultaneously.

Getting Started: A Complete Workflow

Let’s walk through a typical workflow using patman series. First, set up your project (this only needs to be done once):

patman patchwork set-project U-Boot

Now suppose you have a branch video2 with some patches ready to send. Add it to patman’s tracking:

git checkout video2
patman series add

Patman will scan your branch and add it to the database. You might see a warning about unmarked commits – you can either let patman add Change-Id values with -m or tell it not to worry with -M:

patman series add -M

Now send your series:

patman series send

Patman will use git send-email to send your patches and then wait to see if it can automatically find your series on Patchwork. Once linked, you can track its progress. In fact you can see the progress of all your series. Here is an example:

$ patman series progress
Name             Description                               Count  Status
---------------  ----------------------------------------  -----  ---------------
apa              lib: Split fdt_print() into separate libr     4  4:unknown
apb              efi: App and devicetree improvements         20 *20:unknown
app-us           efi_loader: Separate device path into its     3  3:accepted
appc             [00/27] x86: efi: Various app improvement    27  27:n/a
appd             doc: efi_loader: Tidy up the bootefi-comm     2  1:new 1:unknown
bgr2             ACPI fixes                                    4 *4:unknown
blob             [0/4] bloblist: fdt: Clean up the code        5  4:changes 1:unknown
bmg              buildman: Correct behaviour of --in-tree      2  2:new
ci-lab           CI multi-processing                           1  1:n/a
cia              CI improvements                               1  1:changes
efiq3            [v3,00/29] arm: Support building as an EF    36  32:changes 4:unknown
efit             efi: Rename the lib/efi directory             4  4:new
expa             expo: Allow the nominal display-size to b     6  6:n/a
fast             emulation: Improve support for booting fr    19  19:unknown

Series Management Commands

The series subcommand offers a comprehensive set of operations:

Core Operations

  • add: Add a new series to tracking
  • send: Send patches (like patman send but for any tracked series)
  • ls: List all tracked series
  • scan: Rescan a branch to update patch information

Version Management

  • inc: Create next version (v2, v3, etc.) by creating a new branch
  • dec: Delete current version and branch
  • rm-version: Remove specific versions
  • rm: Remove entire series

Patchwork Integration

  • autolink: Find Patchwork link for your series
  • progress: Show upstream status and review progress
  • gather: Collect review tags from Patchwork into commits
  • open: Open series in web browser

Advanced Features

  • mark/unmark: Add/remove Change-Id tags for better patch tracking
  • archive/unarchive: Archive completed series (creates dated tags, deletes branches)
  • patches: Show patches in a specific series/version

Advanced Workflow Example

Here’s how the series feature shines in a real-world scenario:

  1. Initial submission:
   git checkout my-feature
   patman series add -m  # Mark commits with Change-Ids
   patman series send

  1. Address review feedback:
   patman series inc  # Creates my-feature-v2 branch
   # Make your changes...
   patman series send

  1. Track progress:
   patman series progress  # Shows review status
   patman series gather -Cc   # Pulls in Reviewed-by tags, shows comments

  1. Final acceptance:
   patman series archive  # Clean up, create tags

Database-Driven Benefits

The series feature maintains a SQLite database (typically in ~/.config/patman/) that persistently tracks:

  • Series metadata and descriptions
  • Version relationships between branches
  • Patchwork links and IDs
  • Patch Change-Ids for reliable tracking
  • Review status and gathered tags

This database approach means you can switch between projects, reboot your machine, or work on multiple series simultaneously without losing context.

Integration with Existing Workflows

The beauty of patman series is that it builds on top of the existing patman functionality you already know. All the same commit tags (Series-to, Series-cc, etc.) work exactly as before. The series feature simply adds persistent tracking and automation on top.

You can still use regular patman send for quick one-off patches, while leveraging patman series for more complex, multi-version patch series that need ongoing management.

Migration from Manual Workflows

If you’re currently managing patch series manually with git branches and spreadsheets, migrating to patman series is straightforward:

  1. Use patman series add on your existing branches
  2. Let patman discover Patchwork links with patman series autolink-all
  3. Start using patman series send instead of manual git send-email

Conclusion

The patman series feature represents a significant evolution in patch management tooling. By providing database-backed series tracking with deep Patchwork integration, it eliminates much of the manual bookkeeping that makes contributing to large projects tedious.

Whether you’re a seasoned contributor juggling multiple patch series or a newcomer looking to streamline your workflow, patman series offers a compelling upgrade to the traditional patch-by-patch approach. The investment in learning these commands pays dividends in reduced errors, better organization, and more time spent on actual development rather than patch logistics.

Try incorporating patman series into your next contribution workflow – your future self will thank you when managing v4 of that complex patch series becomes as simple as patman series inc followed by patman series send.


The patman series feature is available in recent versions of U-Boot’s patman tool (pip install patch-manager). For complete documentation, see tools/patman/patman.rst in the U-Boot source tree, or here.




EFI app on ARM hits a milestone

The EFI app on x86 has supported booting for a while. With a recent 19-part series, the EFI app can now also boot an OS on ARM. This uses standard boot and the standard extlinux boot flow.


The Core Fixes

To successfully hand off control from the EFI environment to a new operating system, a few key steps must happen in the right order.

  • Exit Boot Services: The most important change is ensuring that U-Boot calls ExitBootServices() before it jumps to the OS kernel. This is a fundamental requirement of the EFI specification. It tells the underlying firmware that its boot-time services (like memory allocation, device I/O, etc.) are no longer needed, effectively handing exclusive control of the hardware over to the operating system.
  • Pass the Memory Map: An operating system needs to know the physical layout of the memory. This series adds the logic to obtain the EFI memory map and write the physical memory information into the Flattened Device Tree (FDT). This allows the Linux kernel to understand the memory layout and manage it correctly.
  • Improved Keyboard Compatibility: On some real-world hardware, such as certain Qualcomm laptops with USB keyboards, simply waiting for a keypress isn’t enough. The underlying system needs time to process other events for the keyboard input to register. The EFI serial driver is updated to use a periodic timer, making the console much more reliable on these devices.
  • General Tidying Up: Alongside these major functional updates, the series includes a lot of valuable code maintenance, such as correcting typos, reorganizing Kconfig options, and standardizing the format of EFI GUID declarations.

Tested and Ready

To ensure this new capability remains robust, the patch series also introduces a new continuous integration (CI) test. We now automatically build the efi-arm_app64 target and use it to boot a full Ubuntu 25.04 image on a QEMU virtual machine in the sjg lab. This provides a strong safeguard against future regressions.


A Note for Testers on QEMU

If you’re planning to test this yourself using QEMU, there’s an important detail to be aware of. The changes do not work correctly with QEMU 8.2 when booting Ubuntu 24.04, as the kernel fails very early in the process with a regime_is_user error.

The good news is that this has been fixed in QEMU 9.2 and newer. So, make sure you’re using an up-to-date version of QEMU for your testing! You can read more about the QEMU issue in this bug report.


Next up?

Work on the app continues, with the goal of having it boot the OS using EFI as well.




Seeing is Believing: Video Support Lands for the ARM EFI App! 🎨

For a while now, U-Boot’s EFI application (efi_app) has been a handy tool, but with one noticeable difference between architectures: x86 could show things on the screen, while ARM was stuck in the dark. If you wanted a splash screen or a graphical boot menu in your ARM EFI app, you were out of luck.

Well, not anymore! A new patch series in Concept closes this gap, bringing full video output capabilities to the ARM EFI application. Let’s dive into how it works.


The Challenge: Drawing Pixels on ARM

The main hurdle for ARM video support within an EFI environment, especially in virtualized setups, is how graphics are handled. Many ARM systems, like QEMU configured with virtio-gpu, don’t provide a simple, direct-access framebuffer to which you can just write the pixel data.

Instead, they rely on the EFI Graphics Output Protocol (GOP) and specifically its Bit Block Transfer function, more commonly known as blt. The blt function is a versatile tool that can copy rectangular blocks of pixels around—from memory to the screen, from the screen to memory, or even from one part of the screen to another.

Thes series uses the blt function to enable video support. U-Boot now draws the display into an in-memory buffer and then uses a blt call to “push” that entire buffer to the visible screen.


A Quick Tour of the Changes

This feature was delivered in a series of seven patches, each building on the last.

  1. Store the GOP (Patch 1/7): The first step was foundational. The existing driver could find the GOP, but it didn’t save the pointer for later use. This patch introduces a private struct (efi_video_priv) to store the GOP handle, making it accessible after the initial probe.
  2. Implement the Blit Method (Patches 2/7 & 3/7): This is the core of the new feature.
    • A new pixel format EFI_GOT_BITBLT is recognized. When detected, the driver knows it must use blt operations instead of writing to a direct framebuffer.A video_sync operation is added, which calls the GOP’s blt function to update the display from U-Boot’s internal framebuffer. An enum, efi_gop_blt_op, was also added to make the code clearer.
  3. Enable a Full Boot Experience (Patches 5/7 & 7/7): What good is a screen if you can’t boot an OS? This series also enables the necessary configs to make the ARM EFI app a fully functional bootloader.

    • CONFIG_BOOTSTD_FULL is now enabled, allowing the app to automatically find and boot an operating system.
    • CONFIG_BOARD_EARLY_INIT_R is turned on to ensure block devices are available.
    • The VBE-OS boot method is also enabled, providing another way to locate and boot an OS.

  4. Supporting Cast (Patches 4/7 & 6/7): A couple of smaller patches provide essential plumbing. The QEMU build scripts were adjusted to prevent conflicts when using multiple disk images, and a fix was added to oftree_dispose() to allow builds where CONFIG_OF_LIVE is disabled.

What This Means for Developers and Users

With these changes, the U-Boot EFI application on ARM is now on par with its x86 counterpart. You can now:

  • Display splash screens for a professional boot experience.
  • Utilize a full graphical console.
  • Use bootstd to automatically scan for and boot an OS from connected block devices.

This makes the ARM efi_app far more useful, particularly in virtualized environments where virtio-gpu is the standard. It provides a complete, visually-enabled pre-boot environment straight out of the box. Go ahead and give it a try with the efi-arm_app64_defconfig! 🚀