Skip to content

support dynamically extending/adding update payloads #766

Open

Description

@cgwalters

See this https://github.com/ondrejbudai/fedora-bootc-raspi/blob/cbff66a8bdb82b6276814765ffdb82c4ec4efa9c/bootupctl-shim#L7

Basically today the bootloader update payload is often part of the base image, but we need to support dynamically extending it with layered image content as well.


In the short term, what may suffice is to offer an explicit user-hookable phase that can copy things from the container to /boot as part of bootc install to-filesystem.

Activity

  1. HuijingHei commented on Nov 20, 2024

    @HuijingHei
    Contributor

    Is this something that teach bootupctl to read config for example: /usr/lib/bootc/install/00-firmware.toml

    [install.firmware]
    type = "bootc-raspi-firmwares"
    

    then it will get install.fimware.type, and find /usr/lib/bootc-raspi-firmwares/, finally copy the files to default directory /boot/efi.

    Or maybe make bootc to read the config file and get install.fimware.type, then pass the env to bootupctl ?

    Not sure if my understanding is correct. Any suggestions? Thanks!

  2. cgwalters commented on Nov 20, 2024

    @cgwalters
    MemberAuthor

    So one thing heavily related to this is today rpm-ostree in "unified core" mode automatically redirects content in /boot to /usr/lib/ostree-boot - so that means the files here:

    rpm -ql bcm2711-firmware
    /boot/efi/bcm2711-rpi-4-b.dtb
    /boot/efi/bcm2711-rpi-400.dtb
    /boot/efi/bcm2711-rpi-cm4-io.dtb
    /boot/efi/bcm2711-rpi-cm4.dtb
    /boot/efi/bcm2711-rpi-cm4s.dtb
    /boot/efi/bcm2712-rpi-5-b.dtb
    /boot/efi/bcm2712-rpi-cm5-cm4io.dtb
    /boot/efi/bcm2712-rpi-cm5-cm5io.dtb
    /boot/efi/bcm2712-rpi-cm5l-cm4io.dtb
    /boot/efi/bcm2712-rpi-cm5l-cm5io.dtb
    /boot/efi/bcm2712d0-rpi-5-b.dtb
    /boot/efi/fixup4.dat
    /boot/efi/fixup4cd.dat
    /boot/efi/fixup4db.dat
    /boot/efi/fixup4x.dat
    /boot/efi/start4.elf
    /boot/efi/start4cd.elf
    /boot/efi/start4db.elf
    /boot/efi/start4x.elf
    

    But dnf does no such thing, so...one simple way to handle this might actually just be changing bootupctl backend install to be idempotent - in the case where the base image already has an /usr/lib/bootupd/updates/EFI.json we extend (regenerating) it.

    In theory though, it would be nicer to represent e.g. shim+grub as a distinct payload from these other blobs?

    Doing that though...hmm, I guess the cleanest way would be for shim+grub to explicitly flag themselves as a unit, or we teach bootc to recognize those directly?

  3. alexlarsson commented on Mar 5, 2025

    @alexlarsson
    Contributor

    For automotive we need more than just put stuff in /boot. For example, if android boot is used, then the boot dir will contain an aboot.img file, and this needs to be written to the boot_a partition. We do ship tools to do the writing, but we need to have a place to hook in callouts to those commands with the right arguments.

  4. cgwalters commented on Mar 5, 2025

    @cgwalters
    MemberAuthor

    Yeah, bootupd abstracts today over the (GRUB) MBR/BIOS case which is a dedicated partition.

    But this is all hardcoded (in Rust) in this project. Adding more bootloaders here I think wouldn't be hard, and the code was definitely designed to enable it.

    But, maybe we could in theory try to rework things such that we have /usr/lib/bootupd/backends with drop-in executables that we fork/exec - in the simplest case of a single bootloader state then bootupd would end up being a really thin wrapper.

    (Unfortunately we do need to think about cases like disk images bootable with both grub BIOS as well as UEFI, so there are conceptually two. But OTOH today that case is grub for both, so maybe we could collapse that into just "grub" conceptually and always update both)

  5. kfox1111 commented on Apr 25, 2025

    @kfox1111

    Has there been any progress on this? interested in simplifying bootc based images on rpi's. Need some way of copying the rpi boot bits onto the boot partiion when its mounted.

  6. cgwalters commented on May 28, 2025

    @cgwalters
    MemberAuthor

    To be clear in this there's two very different cases, though ideally we make them one:

    • Content shipped in an RPM with files in /boot that are present in the initial base image build where bootupctl backend generate-update-payload is invoked
    • Content added after

    So the most ideal thing here would be to again define a generic/extensible/pluggable payload mechanism, and then the cases fold together.

  7. HuijingHei commented on May 29, 2025

    @HuijingHei
    Contributor

    Maybe can teach bootc container lint be aware the files under /boot, then teach bootupd to install them.
    But not sure if bootupctl update should concern about this, as we now only cares about /boot/efi/EFI that comes from grub2/shim.

  8. cgwalters commented on Jun 5, 2025

    @cgwalters
    MemberAuthor

    For the bcm2711-firmware I'd propose a flow like this:

    cd $(mktemp -d)
    dnf download bcm2711-firmware
    rpm2cpio bcm-2711-firmware*.rpm | cpio -div
    bootupctl backend add-esp-content --timestamp <ts> --version $(rpm -q bcm2711-firmware) ./boot/efi
    ```
    
    Crucially we don't need a new payload type I think, the `EFI` one is already a rollup of all files in the ESP and that's all we need.
    
    The `add-esp-content` command would extend what appears in the existing `/usr/lib/bootupd/updates/EFI{,.json}`
    
  9. cgwalters commented on Jun 5, 2025

    @cgwalters
    MemberAuthor

    One might wonder: "Why is this any harder than RUN dnf install bcm2711-firmware"?

    The answer is basically that the rationale for bootupd is that we don't have a mechanism to transactionally update the bootloaders (again see the README.md) and in general it makes sense to split management of the bootloader state from management of the operating system.
    They are different things.

    dnf does no such thing of course today but it doesn't have transactional updates and rollbacks so it doesn't matter.

    Related to this, bootupd puts all the content of bootloader state in /usr, and only copies it into /boot/efi when bootupctl update is invoked. That's why bootupd has this whole concept of "payloads".

    Today, bootc does not automatically run bootupd, but of course some operating systems are shipping the example bootloader-update.service from this repo.

  10. kfox1111 commented on Jun 5, 2025

    @kfox1111

    Interesting. Could that mechanism write outside of /boot/efi (/boot instead) for rpi firmware updates too?

  11. cgwalters commented on Jun 5, 2025

    @cgwalters
    MemberAuthor

    Today, bootc does not automatically run bootupd,

    ➡ more in bootc-dev/bootc#1354

  12. say-paul commented on Jun 9, 2025

    @say-paul
    Collaborator

    Crucially we don't need a new payload type I think, the EFI one is already a rollup of all files in the ESP and that's all we need.
    EFI refers to /boot/efi/EFI
    for rpi 4 firmwares we need to write in /boot/efi instead.

    We can have a function:

    bootc backend install-to-esp bcm2711-firmware-xx.xx.fc42.aarch

    which will do the following:

    cd $(mktemp -d)
    dnf download bcm2711-firmware
    rpm -qpl bcm-2711-firmware*.rpm | grep -q '/boot/efi/' && rpm2cpio bcm-2711-firmware*.rpm | cpio -div || echo "No /boot/efi/ files found in RPM"
    
    

    update /usr/lib/bootupd/updates/ EFI efi.json
    {
    "timestamp": "2025-03-27T10:27:15Z",
    "version": "grub2-efi-x64-1:2.12-28.fc42.x86_64,shim-x64-15.8-3.x86_64,bcm2711-firmware-xx.xx.fc42.aarch"
    }
    along with copying the filetree in /usr/lib/bootupd/updates/efi/{esp.files, EFI/{BOOT,centos/rhel/fedora}}.

    We can also do things in a esp.json with files in usr/lib/bootupd/updates/efi/ to keep things separated

  13. cgwalters commented on Jun 9, 2025

    @cgwalters
    MemberAuthor

    Just to xref @say-paul see also #938 which touches on this a lot, and I think we should land that PR first.

    bootc backend install-to-esp bcm2711-firmware-xx.xx.fc42.aarch

    Well...I am not a huge fan of making anything bootupd (or bootc) automatically call out to something dnf. At least not without it being pluggable (xref bootc-dev/bootc#1105 (comment) )

    Oh oops, I now see I messed up and typed bootc when I meant bootupd in this comment (now edited). We already have the problem in this project (bootupd, not bootc) of some hardcoded dnf references and I was hoping not to add more.

    So anyways again this issue strongly relates to #938 in that what I think we can do is support a flow like this:

    RUN <<EORUN
    set -xeuo pipefail
    # *Today* this will write into `/boot/efi`
    dnf -y install bcm2711-firmware
    bootupctl backend extend-boot-efi
    

    The extend-boot-efi verb would pull content out of /boot/efi and automatically translate it to the (proposed in fedora) new layout of /usr/lib/efi/<name>/<version>/EFI/<contents...>, and then from that we need to translate it into bootupd's current concept of the EFI payload (phew, I know! But I think the proposed new fedora layout is cleaner and we can probably try to migrate our internals to it over time).

  14. kfox1111 commented on Jun 9, 2025

    @kfox1111

    @cgwalters generally sounds like a good plan to me.

    One use case I'm trying to explore is using bootc with a rpi5's with m.2 drives only.

    So far the only firmware I know of that works with it is:
    https://github.com/worproject/rpi5-uefi

    So having some mechanism for dropping that at the root of the boot partition (not /efi) would be very useful, so it can chainload grub.

    Would that work with this proposed mechanism, or would that need to be handled some other way?


    plus 1 for not making new commands depend on dnf. Maybe some wrappers could be provided for various package managers to make that easier, rather then build it into bootupd?

  15. 2 remaining items

  16. cgwalters commented on Jun 9, 2025

    @cgwalters
    MemberAuthor

    Yeah, this issue should cover that one too when completed.

  17. HuijingHei commented on Jun 10, 2025

    @HuijingHei
    Contributor

    The extend-boot-efi verb would pull content out of /boot/efi and automatically translate it to the (proposed in fedora) new layout of /usr/lib/efi/<name>/<version>/EFI/<contents...>, and then from that we need to translate it into bootupd's current concept of the EFI payload

    SGTM.

  18. say-paul commented on Jun 10, 2025

    @say-paul
    Collaborator

    The extend-boot-efi verb would pull content out of /boot/efi and automatically translate it to the (proposed in fedora) new layout of /usr/lib/efi///EFI/<contents...>

    I am skeptical if the layout makes sense when someone wants to put things in /boot
    The workflow I propose:

    1. We can create a method bootupctl extend-boot-payload <payload> payload: /boot, /boot/efi, that copy files to /usr/lib/bootupd/update/BOOT
    2. extend generate-update-metadata() to generate metadata: /usr/lib/bootupd/updates/BOOT.json
    3. extend bootupd backend install to move the files from /usr/lib/bootupd/update/BOOT to /boot , update the bootupd-state.json with the filetree
  19. HuijingHei commented on Jun 11, 2025

    @HuijingHei
    Contributor

    Does it make sense to put the efi files to /boot/efi/BOOT or other directory instead of /boot/efi? It might be helpful when we do updating refer to #454

    Edit:
    Sorry for the confusion, I meant the files like /boot/efi/bcm2711-rpi-4-b.dtb, not grub/shim

  20. say-paul commented on Jun 11, 2025

    @say-paul
    Collaborator

    Does it make sense to put the efi files to /boot/efi/BOOT

    Not at all, I suggested /usr/lib/bootupd/update/BOOT/* to /boot not /boot/efi/.

    Since grub+shim transactions are done in /boot/efi/EFI/<centos/fedora/rhel>
    We need a extend payload mechanism for to extend for /boot/{files,sub-directories}.

  21. say-paul commented on Jun 11, 2025

    @say-paul
    Collaborator

    We can also split the payload extension mechanism to:

    • boot_payload_extension : /boot/{files,sub-directories} except /boot/efi , meta BOOT.JSON , path: /usr/lib/bootupd/update/BOOT/
    • esp_payload_extension: only /boot/efi , meta ESP.json , path /usr/lib/bootupd/update/ESP/ , though it can be merged with EFI.json and /usr/lib/bootupd/update/EFI/ - but I don't know how will it react with existing system.
  22. say-paul commented on Jun 23, 2025

    @say-paul
    Collaborator

    The extend-boot-efi verb would pull content out of /boot/efi and automatically translate it to the (proposed in fedora) new layout of /usr/lib/efi///EFI/<contents...> , and then from that we need to translate it into bootupd's current concept of the EFI payload

    I did this in the #935 , with bit of generalization of accepting input from user, so

    1. we can run bootupd extend-payload-to-esp /boot/efi internally
    2. user can do in containerfile RUN bootupctl backend extend-payload-to-esp <any_path>
  23. travier commented on Sep 9, 2025

    @travier
    Member

    #938 has now landed in a release. Can you try using that layout on Rawhide to install arbitrary files in the EFI partition?

  24. alexlarsson commented on Dec 10, 2025

    @alexlarsson
    Contributor

    @travier It seems to me that #938 only lets you write to /boot/efi/EFI, not /boot/efi (root of ESP partition). The later is required for the raspberry pi firmware. Or am I missing something?

  25. supakeen commented on Mar 13, 2026

    @supakeen

    It would be nice to have the ability to copy directly into the root of the ESP. Right now we have to do pretty dirty workarounds 1 to get images to boot on Raspberry Pi devices while we could have bcm238x-firmware create a dropin for this instead 🙂.

  26. kfox1111 commented on Mar 13, 2026

    @kfox1111

    @supakeen I gave up on trying to bridge the rpi firmware to uefi so bootupd could take over. Its just too slow to gain support for newer pis.

    I implemented this, and its been working very well:
    https://github.com/kfox1111/rpi-bootc-bootloader

    the almalinux base bootc images have been updated to use it as well.

  27. supakeen commented on Sep 17, 2026

    @supakeen

    Note that the previously listed workaround is now also broken. I this commit: bootc-dev/bootc@0d4fadf or bootc-dev/bootc@c0ff1c9f made it so that the mounts are now non-recursive so the bootupd wrapper doesn't actually see /boot/efi and writes directly into /boot/efi (the not-mountpoint but the subdirectory on XBOOTLDR).

    This means we have no way anymore to work around this issue for things that need additional firmware in their ESP (we could find the ESP ourselves inside the wrapper but let's not do really bad things).

  28. cgwalters commented on Sep 17, 2026

    @cgwalters
    MemberAuthor

    Ouch sorry about that @supakeen

    This one needs some careful design, and it just hasn't come to the top yet. The good news is this project is a bit revitalized and we're making momentum on other issues (although, the fix for one of those is what caused this of course)

  29. ericcurtin commented on Sep 20, 2026

    @ericcurtin

    Not the same but somewhat related, was asked to link bootc-dev/bootc#2475

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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