git: 9ecc2493ca5f - main - Restore booting the partition the EFI boot image was loaded from.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 26 Sep 2026 06:44:55 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=9ecc2493ca5fbba852e175674b5cb8975b99af84
commit 9ecc2493ca5fbba852e175674b5cb8975b99af84
Author: Warner Losh <imp@FreeBSD.org>
AuthorDate: 2026-09-26 06:35:41 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-09-26 06:44:20 +0000
Restore booting the partition the EFI boot image was loaded from.
BSDRP images are built with "poudriere image -t firmware", which puts
gptboot.efi on the ESP instead of loader.efi. gptboot.efi reads the GPT
bootme attribute, picks the active system partition (BSDRP1 or BSDRP2),
chainloads /boot/loader.efi from it and hands loader.efi that partition
in LoadedImage->DeviceHandle (stand/efi/boot1/boot1.c:try_boot).
Since ce9bfd78167 ("loader.efi: Refactor try_boot_device_partitions"),
find_currdev() no longer tries that device: try_boot_device_partitions()
walks the parent disk while explicitly skipping dp->pd_handle, on the
assumption that the boot image always comes from an ESP holding no root
filesystem. When chainloaded, the partition gptboot.efi selected is
therefore the one partition never considered, and loader.efi falls
through to the first other UFS partition on the disk - the previous
system. Every A/B upgrade silently boots the old slice.
Commit 1c85c5eea09, which introduced try_boot_device_partitions(), did
try dp itself before its siblings; the refactor dropped it. Restore it,
keeping the sibling walk as the fallback for the normal ESP case.
Fixes: ce9bfd78167
Assisted-by: Claude Code (Fable 5, Opus 5)
Sponsored by: Netflix
---
stand/efi/loader/main.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/stand/efi/loader/main.c b/stand/efi/loader/main.c
index 488e3eb1100b..fa4647101d62 100644
--- a/stand/efi/loader/main.c
+++ b/stand/efi/loader/main.c
@@ -399,9 +399,10 @@ try_disk_and_partitions(pdinfo_t *disk, EFI_HANDLE skip_handle)
}
/*
- * Search the boot device first (i.e. the ESP and any sibling partitions).
- * Per the UEFI specification, filesystems on other devices must not be
- * preferred until the boot device has been fully exhausted.
+ * Search the boot device first (i.e. the device we were loaded from and any
+ * sibling partitions). Per the UEFI specification, filesystems on other
+ * devices must not be preferred until the boot device has been fully
+ * exhausted.
*/
static int
try_boot_device_partitions(void)
@@ -419,6 +420,16 @@ try_boot_device_partitions(void)
efi_free_devpath_name(text);
}
+ /*
+ * Usually this is the ESP, which holds no root filesystem, and the
+ * sibling walk below is what finds the root. But when we have been
+ * chainloaded (gptboot.efi hands us the partition it selected with
+ * the GPT bootme attribute), this is the partition we are meant to
+ * boot from, so it must be tried before its siblings.
+ */
+ if (try_as_currdev(dp, false))
+ return (0);
+
return (try_disk_and_partitions(dp->pd_parent, dp->pd_handle));
}