Raspberry Pi 4 UEFI Booting

I bought a Raspberry Pi 4 with 8GB of RAM and I wanted to try out UEFI on it. I’m happy to say it works and this excites me!

My exact steps:

  1. Connect an FTDI 3.3V logic cable to my Raspberry Pi 4 header, pin 6 is ground (black FTDI wire), 8 is Tx from the RPi (yellow FTDI wire), and 10 is Rx from the RPi (orange FTDI wire). Connect to the FTDI serial port using picocom with baud rate 115200 8n1.
  2. Update the EEPROM by writing the EEPROM updater tool to a micro SD card from GitHub - raspberrypi/rpi-eeprom: Installation scripts and binaries for the closed sourced Raspberry Pi 4 EEPROMs (I used the rpi-boot-eeprom-recovery-2021-04-29-vl805-000138a1-disk-images tag). Boot this and wait until the green LED on the side of the board flashes fast, indicating it’s done.
  3. Using a PC, partition a USB thumb drive to use GPT and create a EFI System Partition (ESP) as the first partition. Format this as vfat, mount it, and unzip the UEFI contents from GitHub - pftf/RPi4: Raspberry Pi 4 UEFI Firmware Images (I used the v1.32 tag). Unmount the USB thumb drive and stick it in your Raspberry Pi 4.
  4. Power up the Raspberry Pi 4 and watch it boot into UEFI!

Console log here: https://gist.githubusercontent.com/bradfa/ef0352ffe5df83447120abf172b15dcf/raw/67fc67f05d0d48a2afdbfb39baecf6bd561cc02a/rpi4-uefi-serial.log

I don’t yet have any OS configured on the USB thumb drive but that’s next. Apparently I’ll need a rather recent Linux kernel (>=v5.7 I believe) in order for all the ACPI things to work enough to be usable (due to past Raspberry Pi support all leveraging device tree).

The only changes I made in the UEFI config menus were to enable the UART as the default console instead of the HDMI outputs and to unblock the 3GB memory limit, since my Raspberry Pi 4 has 8GB of RAM and I want to try using it.

1 Like

My next steps will be to use debos (GitHub - go-debos/debos: Debian OS builder) to build a full Debian disk image including the UEFI. Then I hope to setup the EDKII development environment and build that myself, too.

Being able to use UEFI and ACPI on ARM is not new to me (it’s part of my day-job), but being able to use it on a low cost off the shelf board so that I can learn more should be fun. :slight_smile:

1 Like

Neat! I’ve not used UEFI on ARM yet. What advantages does EFI bring over the classical u-boot (or whatever bootloader) + kernel approach?

The main advantage is you don’t need to doink around with bootloaders. Using UEFI and ACPI makes an ARM board behave just like an x86 desktop or server. You can just take an off the shelf RHEL, Debian, or Ubuntu installer and it’ll just work. UEFI also enables a single disk image to be bootable across many different systems, as long as the kernel has drivers for all those things (distro kernels usually have a tremendous number of modules enabled for this use-case). You don’t need a device tree for each board you want to boot on, ACPI takes care of that as there’s actually a spec and interface format that doesn’t change (unlike device tree).

I’d argue that for a typical embedded product development flow, UEFI and ACPI don’t bring anything to the table over u-boot and device tree. But for things which the customer will treat like a server or desktop, it’s by and far the right way to go, if for no other reason than that’s how everything else does it and people know how to use it.

Unfortunately, the way the Raspberry Pi 4 UEFI works, you have to still stick a bunch of files into the ESP (EFI System Partition) which allow the ROM to properly fetch and execute the UEFI. So the disk itself has to have support for the Raspberry Pi, which is not normal. On a typical UEFI system the ROM support and UEFI itself would live on a separate SPI flash so you can blow away your disk or boot with no disk and still have your UEFI. So the Raspberry Pi UEFI method still has some drawbacks as compared to a normal server or desktop.

1 Like

Thanks, that helps.

Putting the bootloader in SPI flash makes a lot of sense I think for about any system. Then you could have a consistent experience in bootstrapping a system, rather than messing around with every fussy SOC ROM bootloader, special host tools, SD card formats, etc. A SPI flash device is very low cost, so why not …

1 Like

I noticed when my Quickemu machines boot, they are using TianoCore, which appears to be a UEFI implementation.

1 Like

This readme has a list of platforms tianocore EDK supports:

Seems to be mostly high-end devices – not many embedded CPUs I’m familiar with using like TI AMxxxx, or NXP i.MX.

@bradfa Looks a interesting experience, how is the support for multimedia applications (display, video drivers)?

Thanks!

I’m not really sure, sorry. I’ve read that it’s getting better but I expect it won’t work as well as running real Raspbian (or what ever it’s called now).

My use-case for my Raspberry pi is satisfied with a UART console, Ethernet, and USB. I don’t connect the HDMI outputs to anything unless I absolutely have to. My main use case is just to have a quiet armv8 board for Debian packaging work (day-job has loud (for a small office) armv8 boards I support).

Noticed some EFI stuff in u-boot when booting recent Yoe images on the BBB:

U-Boot 2021.01-g316948e851 (Oct 20 2021 - 16:47:40 +0000)

CPU  : AM335X-GP rev 2.0
Model: TI AM335x BeagleBone Black
DRAM:  512 MiB
WDT:   Started with servicing (60s timeout)
NAND:  0 MiB
MMC:   OMAP SD/MMC: 0, OMAP SD/MMC: 1
Loading Environment from FAT... <ethaddr> not set. Validating first E-fuse MAC
Net:   eth2: ethernet@4a100000, eth3: usb_ether
Hit any key to stop autoboot:  0
switch to partitions #0, OK
mmc1(part 0) is current device
Scanning mmc 1:1...
93418 bytes read in 11 ms (8.1 MiB/s)
Scanning disk mmc@48060000.blk...
Disk mmc@48060000.blk not ready
Scanning disk mmc@481d8000.blk...
Found 4 disks
No EFI system partition
BootOrder not defined
EFI boot manager: Cannot load any image
switch to partitions #0, OK
mmc1(part 0) is current device
SD/MMC found on device 1
7361024 bytes read in 488 ms (14.4 MiB/s)
** Bad device specification 1:2 uuid **
93418 bytes read in 10 ms (8.9 MiB/s)
## Flattened Device Tree blob at 88000000
   Booting using the fdt blob at 0x88000000
   Loading Device Tree to 8ffe6000, end 8ffffce9 ... OK
1 Like