[action] [PR:4602] [sonic-installer] Add dedicated SONiC-BMC U-Boot bootloader#386
Merged
Merged
Conversation
Address issue - sonic-net/sonic-utilities#4548 #### What I did Added a **dedicated `BmcUbootBootloader`** so `sonic-installer` manages SONiC-BMC boot state correctly. SONiC-BMC platforms (ASPEED AST2700) run U-Boot with a **two-slot** environment, which the generic `UbootBootloader` does not model — on a BMC it previously fell through to that generic handler and operated on the wrong environment variables. Specifically: - New `sonic_installer/bootloader/bmc_uboot.py` (`BmcUbootBootloader`, `NAME = 'bmc-uboot'`), selected via `utilities_common.chassis.is_bmc()`. - Registered **first** in `BOOTLOADERS` so a stray `/host/grub/grub.cfg` cannot preempt it, and guarded `UbootBootloader.detect()` to exclude BMC. - Full two-slot lifecycle: `list`, `set-default`, `set-next-boot`, `install`, `remove`, `cleanup`, `verify-next-image`, `set-fips`/`get-fips`, `binary-version`, plus a BMC-specific `verify_image_platform` (fails closed). - Unit tests in `tests/installer_bootloader_bmc_uboot_test.py` (12 tests). No change to `sonic_installer/main.py` — the work is confined to the bootloader plugin and its test. #### How I did it `BmcUbootBootloader` subclasses `OnieInstallerBootloader` and models the ASPEED AST2700 two-slot U-Boot environment: | Concept | Slot 1 | Slot 2 | |---------|--------|--------| | version var | `sonic_version_1` | `sonic_version_2` | | boot command | `run sonic_image_1` | `run sonic_image_2` | | kernel args | `linuxargs` | `linuxargs_old` | Empty slots are written/read as the marker `None` (also accepts `NONE`/empty, case-insensitively). - **Boot selection (Aboot-style contract):** `set-default` writes the persistent `boot_next` and clears the one-shot `boot_once`; `set-next-boot` writes only `boot_once`. `get_next_image()` resolves `boot_once` first (it wins, matching U-Boot `bootcmd`), then `boot_next`, and surfaces an empty/unrecognized selector as a raw string so a broken boot state stays visible rather than being masked. - **Install:** `install_image()` runs the image's own installer (`bash <image>`, which performs the slot rotation and sets `boot_next`) and then clears any stale `boot_once` that would otherwise shadow the new default. - **Remove:** `remove_image()` repoints `boot_once`/`boot_next` to the surviving slot before clearing the removed slot's version + auxiliary vars and deleting its rootfs; it refuses to remove the only populated slot. - **FIPS:** `set-fips`/`get-fips` rewrite the `sonic_fips=` token in the target slot's `linuxargs`/`linuxargs_old` only (per-slot isolation). - **Platform check:** `verify_image_platform()` mirrors the GRUB approach — extracts `installer/platforms_asic` from the image and matches the running `device_info.get_platform()` with `grep -Fxq` (whole-line). It **fails closed**: compatible only when grep matches, so a malformed/manifest-less payload is rejected rather than silently accepted. #### How to verify it On a SONiC-BMC (ASPEED AST2700) board, the dedicated bootloader is auto-selected and the full command surface was exercised end-to-end, cross-checking the U-Boot environment (`fw_printenv`) and, across real reboots, `/proc/cmdline`: - `sonic-installer list` / `verify-next-image` reflect the two-slot state. - `set-default <img>` sets `boot_next` and clears `boot_once`; `set-next-boot <img>` sets a one-shot `boot_once` that U-Boot consumes on the next reboot and then reverts to `boot_next`. - `install <bmc.bin>` rotates the new image into a slot and boots it after reboot. - `remove` / `cleanup` clear the slot's vars, repoint the boot selectors, and delete the rootfs. - `set-fips`/`get-fips` toggle `sonic_fips=` in the correct per-slot args. - A wrong-platform (switch) image is rejected by `verify_image_platform`; `--skip-platform-check` overrides it. Signed-off-by: Sonic Build Admin <sonicbld@microsoft.com> #### Previous command output (if the output of a command-line utility has changed) #### New command output (if the output of a command-line utility has changed)
Collaborator
Author
|
Original PR: sonic-net/sonic-utilities#4602 |
Collaborator
Author
|
/azp run |
|
Azure Pipelines could not run because the pipeline triggers exclude this branch/path. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Address issue - sonic-net/sonic-utilities#4548
What I did
Added a dedicated
BmcUbootBootloadersosonic-installermanages SONiC-BMC boot state correctly. SONiC-BMC platforms (ASPEED AST2700) run U-Boot with a two-slot environment, which the genericUbootBootloaderdoes not model — on a BMC it previously fell through to that generic handler and operated on the wrong environment variables.Specifically:
sonic_installer/bootloader/bmc_uboot.py(BmcUbootBootloader,NAME = 'bmc-uboot'), selected viautilities_common.chassis.is_bmc().BOOTLOADERSso a stray/host/grub/grub.cfgcannot preempt it, and guardedUbootBootloader.detect()to exclude BMC.list,set-default,set-next-boot,install,remove,cleanup,verify-next-image,set-fips/get-fips,binary-version, plus a BMC-specificverify_image_platform(fails closed).tests/installer_bootloader_bmc_uboot_test.py(12 tests).No change to
sonic_installer/main.py— the work is confined to the bootloader plugin and its test.How I did it
BmcUbootBootloadersubclassesOnieInstallerBootloaderand models the ASPEED AST2700 two-slot U-Boot environment:sonic_version_1sonic_version_2run sonic_image_1run sonic_image_2linuxargslinuxargs_oldEmpty slots are written/read as the marker
None(also acceptsNONE/empty, case-insensitively).set-defaultwrites the persistentboot_nextand clears the one-shotboot_once;set-next-bootwrites onlyboot_once.get_next_image()resolvesboot_oncefirst (it wins, matching U-Bootbootcmd), thenboot_next, and surfaces an empty/unrecognized selector as a raw string so a broken boot state stays visible rather than being masked.install_image()runs the image's own installer (bash <image>, which performs the slot rotation and setsboot_next) and then clears any staleboot_oncethat would otherwise shadow the new default.remove_image()repointsboot_once/boot_nextto the surviving slot before clearing the removed slot's version + auxiliary vars and deleting its rootfs; it refuses to remove the only populated slot.set-fips/get-fipsrewrite thesonic_fips=token in the target slot'slinuxargs/linuxargs_oldonly (per-slot isolation).verify_image_platform()mirrors the GRUB approach — extractsinstaller/platforms_asicfrom the image and matches the runningdevice_info.get_platform()withgrep -Fxq(whole-line). It fails closed: compatible only when grep matches, so a malformed/manifest-less payload is rejected rather than silently accepted.How to verify it
On a SONiC-BMC (ASPEED AST2700) board, the dedicated bootloader is auto-selected and the full command surface was exercised end-to-end, cross-checking the U-Boot environment (
fw_printenv) and, across real reboots,/proc/cmdline:sonic-installer list/verify-next-imagereflect the two-slot state.set-default <img>setsboot_nextand clearsboot_once;set-next-boot <img>sets a one-shotboot_oncethat U-Boot consumes on the next reboot and then reverts toboot_next.install <bmc.bin>rotates the new image into a slot and boots it after reboot.remove/cleanupclear the slot's vars, repoint the boot selectors, and delete the rootfs.set-fips/get-fipstogglesonic_fips=in the correct per-slot args.verify_image_platform;--skip-platform-checkoverrides it.Signed-off-by: Sonic Build Admin sonicbld@microsoft.com
Previous command output (if the output of a command-line utility has changed)
New command output (if the output of a command-line utility has changed)