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:
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.
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.
Power up the Raspberry Pi 4 and watch it boot into UEFI!
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.
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.
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.
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 β¦
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
Hey . Im new to this and wanted to try the same on RPi , GitHub - pftf/RPi4: Raspberry Pi 4 UEFI Firmware Images this link helped me get to EFI shell but I am unable to get any source to move to the OS , were you able to make this work ? If so can you help me do this ?
P.S : Im very new to UEFI aand ACPI
Yep, thatβs the right link for the Raspi 4 UEFI. If you can get a UEFI shell then youβre most of the way there. You just need to stick an EFI executable into the βremovableβ boot location, which for ARM is within the ESP (EFI system partition) on a fat filesystem on a GPT formatted disk at the path EFI/BOOT/BOOTAA64.EFI
Normally Linux distros will mount the ESP within /boot/efi/ so the full path to the location where you need to stick the EFI executable is /boot/efi/EFI/BOOT/BOOTAA64.EFI
If you use the official Raspberry Pi 4 UEFI binaries from GitHub - pftf/RPi4: Raspberry Pi 4 UEFI Firmware Images then everything is already enabled for UEFI and ACPI on that hardware. Thereβs no need to do anything special.
@bradfa Can you format the disk where the UEFI Firmware Image is at to include the correct EFI directories? If so, do you perform that via a partition (i.e., one for UEFI, one for the bootable FAT32 partition, one for the OS ext4)
Although if youβre booting at least the Raspi 4 (and probably the Raspi 5, but I donβt own one yet) you donβt need the normal bootable FAT32 partition, you just need an EFI system partition (ESP) and then an unencrypted partition where the EFI bootloader (like grub or systemd-boot) can grab the kernel and initrd from. Normally on my Raspi 4 I just have a big giant rootfs (/) partition which includes the /boot/ directory where the kernels live (and if youβre using systemd-boot on Debian then your kernels also live in the ESP itself; theyβre in /boot/ too because of historical and packaging reasons but this is a bit of a tangent).
Thanks @bradfa - Iβve got a system disk that includes the partitions required by using the debos tool along with the Raspberry Pi 4 config. However, Iβm still not getting the UEFI bootloader.
The Pi has the latest firmware (Dec - 2024).
The disk looks like this:
sudo fdisk -l /dev/sdb
Disk /dev/sdb: 29.73 GiB, 31927042048 bytes, 62357504 sectors
Disk model: MassStorageClass
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 9E3AF451-A1FE-434D-AA49-70CDE4BD70EB
Device Start End Sectors Size Type
/dev/sdb1 34 7812500 7812467 3.7G EFI System
/dev/sdb2 7812501 15625000 7812500 3.7G Linux swap
/dev/sdb3 15625001 31328287 15703287 7.5G Linux root (ARM-64)
sdb1 looks like this
drwxr-xr-x 5 root root 4096 Dec 31 1969 .
drwxr-xr-x 5 root root 4096 Jan 15 13:01 ..
drwxr-xr-x 5 root root 4096 Jan 14 18:01 EFI
drwxr-xr-x 3 root root 4096 Jan 14 18:01 fe191f250b5e4b30881bc8d11e825ad2
drwxr-xr-x 3 root root 4096 Jan 14 18:02 loader
sdb2 is the swap file
sdb3 looks like this
total 48
drwxr-xr-x 1 root root 206 Jan 14 17:43 .
drwxr-xr-x 5 root root 4096 Jan 15 13:01 ..
lrwxrwxrwx 1 root root 7 Jan 14 17:36 bin -> usr/bin
drwxr-xr-x 1 root root 192 Jan 14 18:01 boot
drwxr-xr-x 1 root root 128 Jan 14 17:36 dev
drwxr-xr-x 1 root root 2164 Jan 14 18:02 etc
drwxr-xr-x 1 root root 0 Dec 31 05:25 home
lrwxrwxrwx 1 root root 30 Jan 14 17:43 initrd.img -> boot/initrd.img-6.1.0-30-arm64
lrwxrwxrwx 1 root root 30 Jan 14 17:43 initrd.img.old -> boot/initrd.img-6.1.0-30-arm64
lrwxrwxrwx 1 root root 7 Jan 14 17:36 lib -> usr/lib
drwxr-xr-x 1 root root 0 Jan 14 17:36 media
drwxr-xr-x 1 root root 0 Jan 14 17:36 mnt
drwxr-xr-x 1 root root 0 Jan 14 17:36 opt
drwxr-xr-x 1 root root 0 Dec 31 05:25 proc
drwx------ 1 root root 38 Jan 14 17:38 root
drwxr-xr-x 1 root root 96 Jan 14 17:40 run
lrwxrwxrwx 1 root root 8 Jan 14 17:36 sbin -> usr/sbin
drwxr-xr-x 1 root root 0 Jan 14 17:36 srv
drwxr-xr-x 1 root root 0 Dec 31 05:25 sys
drwxrwxrwt 1 root root 0 Jan 14 17:40 tmp
drwxr-xr-x 1 root root 84 Jan 14 17:36 usr
drwxr-xr-x 1 root root 90 Jan 14 17:36 var
lrwxrwxrwx 1 root root 27 Jan 14 17:43 vmlinuz -> boot/vmlinuz-6.1.0-30-arm64
lrwxrwxrwx 1 root root 27 Jan 14 17:43 vmlinuz.old -> boot/vmlinuz-6.1.0-30-arm64
So, everything looks correct β but it appears the bootloader wants a FAT32 partition. Am I understanding this correctly?
Your output seems to be missing pretty much all of the raspi UEFI firmware files and just have the normal data which one would find in an EFI system partition if the UEFI was stored in a SPI flash, like on a normal x86 box.
Raspi doesnβt have such a SPI flash, so sticks the actual UEFI itself in the EFI system partition, hence the variety of firmware binary blobs and device tree files.