UEFI on ARM-V8  based Linux Embedded System

Dear ARM Forum,

I want to understand more about UEFI for ARM-V8 based Embedded systems.

1. Is UEFI on ARM-V8 Linux platform is good or bad ? why ?

2. How UEFI is better than conventional Embedded Booting system?
     First-stage-Boot-loader --> U-Boot --> ATF -->  Linux

3. Support from communities for UEFI on ARMV8 Linux platform ?

4. Documentation for UEFI on ARM-V8 Linux platform ?

5. What are the ARM-V8 HWs already have the  UEFI based development ?

6. Porting efforts from U-Boot based flow to UEFI flow ?

7. Debugging UEFI flow?

8. Any issues that you faced , which lead not to go for UEFI ?

9. Alternatives any ?

Please provide your valuable inputs.


Ravinder Are

  • Hi Ravinder,

    RedHat and other Linux workstation and server products require UEFI for support of ARMv8 hardware. The 96Boards EE platforms will come with it. And it is well-placed to support ACPI, which is a requirement of Enterprise environments, and specified these days by the UEFI ACPI Working Group (ASWG). Apart from that we (ARM) don't have a strong opinion on it, although we're a UEFI Forum member.

    Your boot flow sequence is wrong (perhaps just too simple), by the way: it's usually FSBL -> ATF -> U-Boot -> Linux. The difference is that U-Boot is replaced with UEFI, if you want to use UEFI (see below).

    The difference between UEFI is well-described in the UEFI specification, it provides API interfaces to the operating system to access the protocols underneath (which may be device drivers like UART, disk, or protocols like TCP/IP, or USB HID) and to describe the system memory map and capabilities.

    U-Boot has a side-effect, without that standardisation, to expose various other quirks and differences which, while not being a showstopper for most people, can make installing an Operating System (and sometimes booting it..) rather frustrating. I regularly find an older board and I have to actually look up how on earth I managed to boot it in years past. With UEFI platforms I just turn them on and put a kernel on a USB stick.. UEFI has a standard Shell (as does U-Boot), and you can write scripts for that Shell. You can load applications, which could also install new Drivers via the DXE, and then exit back to the Shell or a bootloader. You can define a menu just like a PC BIOS menu, or even make one of those fancy UEFI Menus with some work.

    As an example, the GRUB bootloader uses UEFI to access the display, input, storage media and read files like Linux kernels and ramdisks/device trees, show progress bars, graphical menus, meaning it is relatively lean in terms of actual driver support in whatever it loads - the application or OS kernel it simply accesses the UEFI driver support until it can load it's own drivers, or may be able to exist without it's own drivers at all (as GRUB would). If it is a chain loader like GRUB, then it simply loads another application (or another kind of executable) and passes control, and that application that would then gain access to UEFI.

    Under U-Boot you'd have to implement that in U-Boot, and by implication, you would have to expect GRUB to do less - if U-Boot did not put the files in memory, GRUB can't go out and load them from disk as U-Boot provides no interface for GRUB to read the storage media. Alternatively, you can re-implement drivers in GRUB. Consider that you may have a disk driver in U-Boot, one in GRUB, and one in Linux that was built-in to the kernel (not a module..), and a mouse driver, and a keyboard driver. UEFI allows you to have one stage of boot not have to use drivers, and it's even possible in some cases (as above) to never implement your own driver if UEFI already has support (up to the point you tell UEFI that you don't need it). As another example, you can actually boot Linux directly from UEFI, and pass it parameters to use UEFI to load it's own ramdisk without a disk driver built-in, to print to the display without knowing precisely how to configure DACs and transmitters and fetch EDIDs on the low-level hardware.

    You can change UEFI boot order and other settings with runtime services variables which follow a standard, but as above on U-Boot that's somewhat platform-specific, despite some attempts at standardisation, and requires OS driver support for those specific platform methods. For UEFI the boot variables are a service, which requires a driver, but it's the same driver on all platforms (in fact, the same Linux driver on ARM as on Intel). You can also tell UEFI to update itself - by loading a "Capsule" - or even other devices on a system such as GPU or WiFi firmware, or embedded controller (laptop keyboard and trackpad, for instance), which should be loaded and flashed before or without intervention by the OS, for example. That removes the need for Linux to contain any specific board flashing or updating code. UEFI also allows for code signing (SecureBoot) of applications or OS in a standard manner - U-Boot does not. However, while there are many ways to say UEFI is better than U-Boot, UEFI is definitely more complicated to code for (not in terms of API or specification, but the sheer size of the current codebase, and the contributor license).

    U-Boot is more accessible, and leaner. Some would say UEFI is larger as a firmware binary, but I have U-Boot platforms with 1MB U-Boot, and the same platforms have similar functionality with a 700K UEFI. That said, I can make that U-Boot build about 250K if I wanted to play with it. To summarize that, UEFI gives your ARM platform the same flexibility on booting as a standard PC. U-Boot gives you a more tightly-controllable environment for more constrained use cases.

    There're plenty of communities, including this one. From a Linux perspective the Linux ARM Kernel Mailing List is a good place to chat about it.

    For documentation, not from a Linux perspective, but from a UEFI perspective, the specifications and documentation are at the UEFI website - UEFI isn't tailored to any particular OS, so from an "ARMv8 Linux" perspective you can simply ignore the Linux part (and the ARMv8 part - UEFI specification supports ARMv4 and above!). If you need a platform that has UEFI, the 96Boards EE boards, some of the 96Boards CE boards (not an exhaustive list - check around, there are several), and ARM's Juno platform is obviously UEFI-ready.

    There shouldn't be any "porting efforts" with regards to flow. UEFI has a different model, it loads UEFI Applications, and the Linux kernel is basically an application. It can then control UEFI and tell it to get out of it's way (via ExitBootServices). If you are using ATF, then UEFI or U-Boot are essentially "BL3-3" and ATF handles the details of how to get to UEFI or U-Boot via the entry point. You would obviously have to write some drivers for a new platform, but there is a lot of documentation on how to do so and a lot already exist. Once you have a system, there's a nice article here on this site about debugging UEFI using ARM tools.