Skip to content

Firmware handling of upstream kernel and Device Tree files #3237

@pelwell

Description

@pelwell

Although most users are unaware of it, the RPi firmware has special support for "upstream" (compiled from source code found on kernel.org) Linux kernels and Device Tree files. Specifically, the upstream_kernel=1 flag can be used to request that the relevant upstream DTB files are loaded, falling back to the downstream variants as necessary and applying the upstream overlay to help bridge the gap between the two worlds.

This mechanism has relied on the fact that the upstream developers have used a different naming convention for their DT files, basing them on the package name (BCM283x) as opposed to the die name (BCM27xx) (*). The Pi 4B SoC chip is called BCM2711 - there is no BCM2838, although the name is guaranteed free for use - and against expectations the upstream devs have chosen to also use bcm2711 as their SoC identifier. This will break the select-by-filename logic used up to now, so an alternative is needed.

Another little-known firmware feature is the ability to request that overlays are loaded from a different subdirectory of the boot partition (on SD card or network share). This is controlled by the overlay_prefix setting, the default for which is overlays/.

A third item for consideration is that it would be useful to be able to store multiple independent operating systems on a single image and select between them at boot time based on a config.txt setting. This would allow (for example) a "recovery" OS for the case when a bad kernel build prevents the device from booting (almost a daily occurrence for me, sometimes). I've recently implemented a physical "64-bit switch" on my daily driver Pi4 that pulls GPIO5 to ground, activating the [gpio5=0] section that sets arm_64bit=1. It would be nice to be able to extend that to multiple alternate builds of the same kernel type, etc.

Pulling these strands together brings me to suggest a new config.txt setting - os_prefix. The default value would be the empty string, but if set it would be prepended to the names of "OS" files. Booting with os_prefix=backup- might load backup-kernel.img, whereas os_prefix=backup/ would cause the firmware to look in the backup directory.

What constitutes an "OS" file? The kernel, .dtbs and cmdline.txt definitely fit the description, and I'm declaring that the firmware files (bootcode.bin, start*.elf, fixup*.dat) don't. Overlays fall into a grey area - making them OS-specific is conceptually cleanest and most flexible, making them common saves a small amount of space. I'm leaning towards a hybrid scheme whereby the firmware looks for ${os_prefix}${overlay_prefix}README(**) and, if found, sets overlay_prefix to ${os_prefix}${overlay_prefix}, otherwise leaving it unchanged. This allows shared and unshared overlays, but prevents a pick-and-mix approach.

The proposal for the handling of upstream files is that setting upstream_kernel=1 has an implicit side-effect of setting os_prefix=upstream/ (unless os_prefix is explicitly set). Putting all upstream kernel files into a subdirectory allows upstream and downstream to coexist, regardless of the names of the individual files.

N.B. os_prefix and upstream_kernel only affect automatic file selection - they have no effect on explicit cmdline=, kernel=, device_tree= and ramfsfile= settings which are always relative to the root of the boot partition (or the network equivalent).

Does anybody have any improvements to suggest or concerns about this approach?

(*) This could be the wrong way round - all that matters is that that each chip effectively has two names.
(**) The network and USB boot mechanisms don't have a way to test for the existence of a directory, only a file (and in the case of a non-directory prefix it wouldn't make sense anyway) so test for the existence of the README instead.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions