Re: Review D58990: freebsd-update: automatically update EFI and BIOS bootloaders on install
Mark Millard <[email protected]>
| Newsgroups | gmane.os.freebsd.devel.hackers |
|---|---|
| Message-ID | <[email protected]> |
On 8/20/26 08:26, Mark Millard wrote: > On 8/20/26 01:08, Ronald Pagani Jr (ronald.pagani.jr) wrote: >> >> >> On Thu, Aug 20, 2026 at 12:37 AM Stefan Esser <[email protected] >> <mailto:[email protected]>> wrote: >> >> Am 19.08.26 um 18:30 schrieb Ronald Pagani Jr (ronald.pagani.jr): >> > I've submitted a patch to automatically update the EFI bootloader >> on the ESP >> > during freebsd-update install: >> > >> > https://reviews.freebsd.org/D58990 <https://reviews.freebsd.org/ >> D58990> <https://reviews.freebsd.org/D58990 <https:// >> reviews.freebsd.org/D58990>> >> > >> > The problem: freebsd-update updates /boot/loader.efi on the root >> filesystem, >> > but the UEFI firmware boots from loader.efi on the EFI System >> Partition — a >> > separate FAT32 partition that freebsd-update never touches. After >> a major >> > version upgrade the ESP loader can be left several versions stale. >> Since 14.1 >> > removed the lua_path==nil compatibility shim from core.lua, this >> mismatch >> > produces a hard boot failure. If the user also ran zpool upgrade, >> the system is >> > completely unbootable without external media. >> > >> > The patch hooks efi_bootloader_update.sh into install_run() in >> freebsd- >> > update.sh. It auto-detects the ESP via gpart, fingerprints /EFI/BOOT/ >> > BOOTx64.efi before touching it (multi-OS safe), creates /EFI/ >> FreeBSD/loader.efi >> > if absent, updates NVRAM, and handles BIOS GPT bootcode as well. >> Opt-out via >> > UpdateBootloader=no in freebsd-update.conf. >> > >> > Tested on FreeBSD 14.0-RELEASE-p11 amd64 (UEFI, ZFS, NVMe). 197 unit/ >> > integration/error tests available at: >> > >> > https://github.com/RZA-SF/freebsd-patch-for-bug279829 <https:// >> github.com/RZA-SF/freebsd-patch-for-bug279829> <https://github.com/ >> RZA- <https://github.com/RZA-> >> > SF/freebsd-patch-for-bug279829> >> >> I'm using a much simpler version that just covers my setup, and would >> like to replace it by a more general version. >> >> This fails for me in lines 231 to 236 since device names are expected, >> but zpool status returns a diskid based path: >> >> $ zpool status zroot >> pool: zroot >> state: ONLINE >> config: >> >> NAME STATE READ WRITE CKSUM >> zroot ONLINE 0 0 0 >> diskid/DISK-8ESKF03YZ0EAp2 ONLINE 0 0 0 >> >> errors: No known data errors >> >> $ sh efi_bootloader_update.sh --dry-run >> freebsd-update: [bootloader] INFO: Boot method detected: UEFI >> freebsd-update: [bootloader] WARN: No boot disks found >> freebsd-update: [bootloader] WARN: Boot disk discovery failed >> freebsd-update: [bootloader] WARN: If using hardware RAID or an exotic >> topology, update the bootloader manually >> >> My version uses "gpart show -p" to list boot partitions and to fetch >> the corresponding device names: >> >> $ gpart show -p | grep -w efi >> 2048 522240 diskid/DISK-8ESKF03YZ0EAp1 efi (255M) >> 2048 522240 diskid/DISK-81S0A0K7FJDHp1 efi (255M) >> 2048 522240 diskid/DISK-81S0A0L1FJDHp1 efi (255M) >> >> > This is complementary to Warner Losh's D45890 (loader version- >> check warnings). >> > Feedback welcome. >> Regards >> STefan >> >> >> >> I've just pushed a kern.disks implementation following recent review >> comments, and I'm wondering if that works for you? >> >> https://github.com/RZA-SF/freebsd-patch-for-bug279829/blob/revision-2/ >> src/efi_bootloader_update.sh <https://github.com/RZA-SF/freebsd-patch- >> for-bug279829/blob/revision-2/src/efi_bootloader_update.sh> >> >> >> Best, >> Ron >> > > On a Windows Dev Kit 2023 (with UFS) it gets: "freebsd-update: > [bootloader] INFO: Boot method detected: unknown" > > # sh -x efi_bootloader_update.sh --dry-run --verbose > + [ -n '' ] > + _EFI_BOOTLOADER_UPDATE_SH=1 > + : /boot/loader.efi > + : 0 > + : 0 > + : 1 > + : /boot/pmbr > + : /boot/gptzfsboot > + : /boot/gptboot > + _EFI_FINGERPRINT_THRESHOLD=2 > + _efi_esp_mp='' > + _efi_esp_did_mount=0 > + _efi_tmp_mounts='' > + _efi_script_name=efi_bootloader_update.sh > + [ efi_bootloader_update.sh '=' efi_bootloader_update.sh ] > + [ 2 -gt 0 ] > + EFI_DRY_RUN=1 > + shift > + [ 1 -gt 0 ] > + EFI_VERBOSE=1 > + shift > + [ 0 -gt 0 ] > + update_bootloaders > + local 'total_errors=0' > + local rc > + efi_check_prerequisites > + local 'ok=0' > + id -u > + [ 0 '!=' 0 ] > + sysctl -n security.jail.jailed > + [ 0 '=' 1 ] > + [ ! -f /boot/loader.efi ] > + [ ! -s /boot/loader.efi ] > + return 0 > + rc=0 > + local boot_method 'fallback_binary=' > + efi_boot_method > + local m > + sysctl -n machdep.bootmethod > + m='' > + echo unknown > + return > + boot_method=unknown > + _efi_info 'Boot method detected: unknown' > + _efi_log 'INFO: Boot method detected: unknown' > + echo 'freebsd-update: [bootloader] INFO: Boot method detected: unknown' > freebsd-update: [bootloader] INFO: Boot method detected: unknown > + [ unknown '=' UEFI ] > + trap efi_cleanup_mounts EXIT INT TERM > + [ unknown '=' UEFI ] > + local bios_list > + efi_discover_all_bios_parts > + local disks > + sysctl -n kern.disks > + tr ' ' '\n' > + disks='da0 > nda0' > + local disk 'found=0' > + [ -z da0 ] > + local parts > + gpart show da0 > + awk -v 'd=da0' '$4 == "freebsd-boot" { print d, $3 }' > + parts='' > + [ -n '' ] > + [ -z nda0 ] > + local parts > + gpart show nda0 > + awk -v 'd=nda0' '$4 == "freebsd-boot" { print d, $3 }' > + parts='' > + [ -n '' ] > + [ 0 -eq 0 ] > + return 1 > + bios_list='' > + true > + [ -n '' ] > + [ 0 -gt 0 ] > + [ 1 '=' 1 ] > + _efi_info '[DRY RUN] Bootloader update complete (no changes made)' > + _efi_log 'INFO: [DRY RUN] Bootloader update complete (no changes made)' > + echo 'freebsd-update: [bootloader] INFO: [DRY RUN] Bootloader update > complete (no changes made)' > freebsd-update: [bootloader] INFO: [DRY RUN] Bootloader update complete > (no changes made) > + return 0 > + exit 0 > + efi_cleanup_mounts > + local mp > + _efi_tmp_mounts='' > > (I had reported the empty sysctl -n machdep.bootmethod result for the > context in the review, violating an assumption of the scripting. I've no > clue how common the empty result might be overall.) > I tried another (but unofficial) context: Booting a RPi5B via a draft/partial EDK2 on a microsd card and the FreeBSD materials (including ESP) on the internal NVMe. So, another UEFI/ACPI aarch64 context: # sh -x efi_bootloader_update.sh --dry-run . . . + efi_boot_method + local m + sysctl -n machdep.bootmethod + m='' + echo unknown + return + boot_method=unknown + _efi_info 'Boot method detected: unknown' + _efi_log 'INFO: Boot method detected: unknown' + echo 'freebsd-update: [bootloader] INFO: Boot method detected: unknown' freebsd-update: [bootloader] INFO: Boot method detected: unknown . . . So the same issue. (There is no U-Boot context for that RPi5 context that I know of for FreeBSD.) I'll note (both aarch64): WinDevKit23: # efibootmgr BootCurrent: 0000 RPi5: # efibootmgr Boot to FW : false BootCurrent: 0002 Timeout : 5 seconds BootOrder : 0000, 0001, 0002, 0003 Boot0000* UiApp Boot0001* UEFI SanDisk SE32G 4412AC09 SD Device +Boot0002* UEFI Timetec 35TTTN2242GE3P-1TB YS240913B1T0242 1 Boot0003 UEFI Shell I do not know if the efibootmgr behavior intended always works. There is a notable difference in the default outputs above, WInDevKit23 possibly being odd. As for the amd64 system, just for reference: # efibootmgr Boot to FW : false BootCurrent: 0004 Timeout : 1 seconds BootOrder : 0000, 0002, 0004, 0006, 0005, 0007, 0008 Boot0000* Windows Boot Manager Boot0002* UEFI OS +Boot0004* UEFI OS Boot0006* UEFI OS Boot0005* UEFI OS Boot0007* UEFI OS Boot0008* UEFI OS (It actually boots Windows 11 Pro by default, even though that is normally not what I boot.) I'm avoiding touching the systems that I have access to. I may later see about trying an official U-boot based UEFI boot context on, say, an RPi4B. -- === Mark Millard marklmi at yahoo.com