It's Pi all the way down...

Groovy Boot Modes

Wed 21 October 2020
by Dave Jones

By default, Ubuntu Groovy Pi images (both Server and Desktop) will ship with a boot sequence that involves the Pi’s native bootloader only. In other words, the new boot sequence is simply:

Pi Bootloader --> Linux Kernel --> Initrd

Previous versions of Ubuntu on the Pi have included U-Boot in the sequence. In other words, in Focal (and prior) versions, the boot sequence was:

Pi Bootloader --> U-Boot --> Linux Kernel --> Initrd

Users upgrading to Groovy will continue using the legacy U-Boot sequence but are free to switch to the new “native only” boot sequence by following the instructions below. Conversely, new users of Groovy may also switch to a U-Boot based sequence if they so wish (the U-Boot binaries will still be installed on the boot partition even when they’re not used to enable switching between the two choices).

Note

Be aware that the U-Boot based sequence does not support native USB boot, or the Pi’s native netboot (U-Boot on the Pi 3 and earlier does have its own PXE-like netboot system, however our build of U-Boot currently lacks ethernet drivers for the Pi 4).

Also note that the U-Boot based sequence is now deprecated. If you are still relying on U-Boot for some reason, please let me know what it is (open a ticket against u-boot on Launchpad, leave a comment below, or pester me on Twitter)!

Switching from U-Boot to Native

The only file that needs editing is /boot/firmware/config.txt. There may be warnings at the top of the warning you not to edit it. You can ignore these. I know this, because I wrote them (you can read the sordid tale of those warnings and why they’re now redundant in this post).

Remove any existing lines that start with kernel=, initramfs, or devicetree_address= from this file. The add the following lines under the [all] section:

kernel=vmlinuz
initramfs initrd.img followkernel

That’s all there is to it! If you want to try this from pibootctl (with some extra lines to save your current boot configuration so you can switch back to it if you wish), the following commands should do the trick:

$ sudo pibootctl save uboot
$ sudo pibootctl set boot.kernel.filename=vmlinuz \
    boot.initramfs.filename=initrd.img boot.devicetree.address=
$ sudo pibootctl save native

Now you can simply do the following to switch back to uboot if you wish:

$ sudo pibootctl load uboot

Switching from Native to U-Boot

Switching back to U-Boot from the native boot sequence is a little more complex but not much so. Again, in /boot/firmware/config.txt remove all lines that start with kernel= or initramfs. Next, determine whether you’re using a 32-bit or 64-bit:

$ dpkg --print-architecture
arm64

If you’re on arm64 (64-bit), you want a config.txt that includes the following (by “includes” I mean don’t replace your whole configuration with this; either append this to your current configuration or merge it into the existing sections - either should be fine):

[pi4]
kernel=uboot_rpi_4.bin
max_framebuffers=2

[pi2]
kernel=uboot_rpi_2.bin

[pi3]
kernel=uboot_rpi_3.bin

[all]
arm_64bit=1
device_tree_address=0x03000000

If you’re on armhf (32-bit), you want a config.txt that includes the following:

[pi4]
kernel=uboot_rpi_4_32b.bin
max_framebuffers=2

[pi2]
kernel=uboot_rpi_2.bin

[pi3]
kernel=uboot_rpi_3_32b.bin

[all]
device_tree_address=0x03000000

(if you’re curious about the strange ordering of the sections, this isn’t strictly required on Groovy but is just there for historical reasons)

You can try this doing this via pibootctl, but it currently only has options for modifying boot configuration sections relevant to the machine you’re running on (e.g. if you’re on a Pi 4, it can modify the [pi4] and [all] sections but won’t modify [pi2] or [pi3] sections). So, if you’re on a Pi 4 running an arm64 kernel, you could do the following (with some extra lines to save your current boot configuration so you can switch back to it if you wish):

$ sudo pibootctl save native
$ sudo pibootctl set --this-model boot.kernel.filename=uboot_rpi_4.bin
$ sudo pibootctl set --no-backup boot.initramfs.filename= \
    boot.devicetree.address=0x3000000
$ sudo pibootctl save uboot

Now you can simply do the following to switch back to uboot if you wish:

$ sudo pibootctl load native