Created attachment 168070 [details] patch for efi boot1 partition selection Current efi boo1 allows boot from auto-selected (first match) partition only. I write patch to allow boot-time partiton selection for boot1.efi.
Out of interest why would this be needed? Also as rule upload the patch without compression it and flag it as a patch as that makes it easer to quickly review.
(In reply to Steven Hartland from comment #1) Sorry for inadequate format. It's my first PR and I couldn't find these rules in Web page. I'll do in next time. I wrote this patch to select booting 10.3 or 11 which are installed on different partitions in one HD. It's useful for me.
Created attachment 168264 [details] boot1.c.diff Decompress the originally attached patch.
Add this PR as dependency to https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=203349 ?
Created attachment 168291 [details] boot1 patch rev2 - add input timeout
I created patch rev2 which has input timeout functionality. So, now it works as original if there are no key in. I'm not English native tonge. It's helpful if someone check this patch's displaying messages.
(In reply to Steven Hartland from comment #1) Comparing with MBR ones, current in-tree version (you fixed recently) corresponds to boot0 (512 bytes version), while Naomichi's first version corresponds to boot0ext (1024 bytes version). And Naomichi's second version is the combined one. If someone using boot0ext wants to move to UEFI(GPT) environment, Naomichi's one would help.
(In reply to Naomichi Nonaka from comment #6) Tried, and working as expected for me. ThinkPad T420 with 2 drives (second one is in UltraBay adapter), each drive have one UFS partition and one ZFS pool. The default matches current in-tree boot1.efi, either booted from internal first drive or second drive in UltraBay. *Means that if I select first drive with UEFI firmware, ZFS pool in first drive is auto-selected, and that if I select second drive, ZFS pool in second drive is auto-selected.
(In reply to Tomoaki AOKI from comment #8) That would work without this change.
(In reply to Steven Hartland from comment #9) I know. :-) I mean that rev.1 of Nomichi's patch always required manual-select of partition, without default and timeout, but in rev.2, default selection (compatible with already MFC'ed version) is added as #0 with timeout support.
I tested on 10.3-RELEASE. The patch can be applied without errors. Original version of boot1.efi on an internal drive can boot from an external drive, if I connected an external drive. The rev2 patched version of boot1.efi on an internal drive can boot only from the same internal drive. I want to be able to boot from other drives.
(In reply to Masachika ISHIZUKA from comment #11) Mr. ISHIZAKI, Thanks for testing. I tried, but in my PC, both 10.3-boot1.efi and my rev2 boot1.efi in internal drive can boot to internal drive only. If you want to boot from external drive, you can choose external drive in "UEFI boot drive selection" menu. It is helpful for me if you could show details such as 1. your external drive is MBR partition or GPT partition. 2. what partitions are shown in rev2 patched boot1.efi. 2a you can't see external drive in boot1.efi's partition list. or 2b you see external drive in list, select it, but booted from internal 3 your external drive is connected via USB or eSATA. Regards, Naomichi Nonaka
(In reply to Naomichi Nonaka from comment #12) Thank you for your reply. I think this problem seems to come from my PC's EUFI bug. > 1. your external drive is MBR partition or GPT partition. GPT partitions. > 2. what partitions are shown in rev2 patched boot1.efi. > 2a you can't see external drive in boot1.efi's partition list. or > 2b you see external drive in list, select it, but booted from internal Both of external and internal drive has only one partition of freebsd-boot each, select menu was not displayed. % gpart show ada0 <--- internal drive => 34 500118125 ada0 GPT (238G) 34 2014 - free - (1.0M) 2048 1024000 1 efi (500M) <- EFI 1026048 81920 2 ms-basic-data (40M) 1107968 262144 3 ms-reserved (128M) 1370112 127845242 4 ms-basic-data (61G) <--- win10pro 129215354 1158 - free - (579K) 129216512 931840 5 !de94bba4-06d1-4d40-a16a-bfd50179d6ac (455M) 130148352 121923584 6 ms-basic-data (58G) <--- win8.1pro 252071936 954368 7 !de94bba4-06d1-4d40-a16a-bfd50179d6ac (466M) 253026304 2048 - free - (1.0M) 253028352 3807104 8 ms-basic-data (1.8G) 256835456 128 9 freebsd-boot (64K) <- 10.3R boot 256835584 8388608 10 freebsd-ufs (4.0G) <- 10.3R / 265224192 16777216 11 freebsd-swap (8.0G)<- 10.3R swap 282001408 16777216 12 freebsd-ufs (8.0G) <- 10.3R /var 298778624 16777216 13 freebsd-ufs (8.0G) <- 10.3R /usr 315555840 33554432 14 freebsd-ufs (16G) <- 10.3R /home 349110272 134217728 15 freebsd-ufs (64G) <- 10.3R /usr/local 483328000 16788144 16 !d3bfe2de-3daf-11df-ba40-e3a556d89593 (8.0G) 500116144 2015 - free - (1.0M) % gpart show da0 <--- external USB drive => 34 3907029097 da0 GPT (1.8T) 34 1606 - free - (803K) 1640 88 2 freebsd-boot (44K) <- 11.0-current boot 1728 134217728 3 freebsd-ufs (64G) <- 11.0-current / 134219456 16777216 4 freebsd-swap (8.0G)<- 11.0 swap 150996672 3756032459 - free - (1.7T) /dev/da0p1 was EFI partition, but if it exist, my PC's UEFI menu has broken, it may be bug on my PC. So 'gpart delete -i 1 da0' was excuted. > 3 your external drive is connected via USB or eSATA. via USB I can remove win8.1pro and if I can select boot partitions for FreeBSD without setting bootme, I will install 11.0-current to internal drive. My PC's EUFI is too buggy and sometimes halt on startup DELL logo when changing the UEFI boot options. If it happens, I have to remove the battery and remove the SSD with opening the case of PC, I don't want to change UEFI options.
Thank you for quick reply. > select menu was not displayed. It means boot1 found only 1 bootable partition. I might think boot1 could not recognize external drive is "varid" because of lack of EFI partiotion. Sorry, it may take some time to prepare test environment. > I can remove win8.1pro and if I can select boot partitions for FreeBSD without setting bootme, I will install 11.0-current to internal drive. I assume rev2 boot1 can do that. It's (almost) same configuration as my test PC. I'm very happy if you try. But, unfortunately, there are too many variant and bugs in UEFI firm, I can't tell if it really work or not. sigh.
OK, I found my mistake. I had written "set boot_disk_unit=0" in /boot/loader.conf. after removing that line. rev2 boot1 can boot to external drive. # I wrote that line in very early stage of my testing and forgot that. for boot drive choise, I found 10.2R boot1.efi boot to external drive. So I assume Mr. ISIZUKA had installed 10.2R to internal drive, and when upgraded to 10.3R, boot1.efi had not upgraded to 10.3R. You can check size of boot1.efi. 10.2R is about 33K, 10.3R is about 74K, and rev2 is about 82K. Summary: when both internal drive and external drive have bootable partition. *10.2R boot1.efi -> autoboot to external drive *10.3R boot1.efi -> autoboot to internal drive *rev2 boot1.efi -> show partition list. can boot to either internal or external by keyin timeout boot to internal
(In reply to Naomichi Nonaka from comment #15) Thank you for your report details. % ls -l /mnt2/EFI/freebsd/boot1.efi -rwxr-xr-x 1 ishizuka j5p 33262 Sep 19 2014 /mnt2/EFI/freebsd/boot1.efi My boot1.efi is very older than 10.3R. By the way, ver2 boot1 it did not work cause was found in my PC. Again my PC of UEFI of the bug was due. Input waiting loop for 10 seconds is done at the moment, and keyboard input is not recognized. Then, timer and keyboard input is restored to within to change several times a UEFI option on my PC, now works properly. I'm sorry to you fuss. The external UBS disk and internal disk is selectable by ver2 boot1 loader on internal disk.
Created attachment 169420 [details] small change I changed the following to ver2 patch. (1) when push any key other than partition select number or retry of boot failure, timeout count is stopped. (2) partition number is decimal with p, ie hd(a)-> hd(p10). (3) partition size is shown, ie hd(p10) (100G). (4) maximum partition number(NUM_DEV_LIST) for selection is 35. (5) number on select menu is shown in both the left and right. Actually it labels also wanted to display, but I have to give up because it is a little difficult going.
Created attachment 170131 [details] boot1.c patch rev3
(In reply to Masachika ISHIZUKA from comment #17) I just posted patch rev3. which * merged Mr.ISHIZUKA's changes * improve event handling. now no key input delay. * changed UI so that * space key stops timeout * enter key means selecting autoboot (key 0) I hope you try this. thanks.
(In reply to Naomichi Nonaka from comment #19) Thank you for ver3 patch. Although this is almost good for me, I have some minor comments. > * enter key means selecting autoboot (key 0) line number 521 should be "if (c == '\r') {". And line number 550 should be "move_to_tol();" to prevent from "Select from 0 to b. Timeout in 10 seconds, [Space] to pause : Select from 0 to b. Timeout in 10 seconds, [Space] to pause : " when I pressed 'z'.
Created attachment 170241 [details] boot1.c patch rev4 Bug fix. Thanks to Mr.ISHIZUKA. Naomichi Nonaka
(In reply to Naomichi Nonaka from comment #21) Thank you for ver4 patch. It works fine.
The patch can be applied on FreeBSD 11.1-RELEASE but not anymore on FreeBSD 11.2-RELEASE due to big change in boot1.c. For exemple, hd->PartitionNumber didn't exist anymore in boot1.c of FreeBSD 11.2-RELEASE. Anyone can make this patch working on 11.2-RELEASE ? Many thanks
See https://svnweb.freebsd.org/changeset/base/329114 for big changes done between 11.1-RELEASE and 11.2-RELEASE.
Created attachment 194818 [details] boot1.c patch rev4 for stable/11 r330813 and later Quick and ugly hack by mainly reviving deleted-but-needed-for-patch codes. Should be applicable to 11.2, as releng/11.2 branched after r330813 (at r334459). I had not enough time to dig into code changes to be tracked. :-(
Many thanks for the updated patch. It apply without any issue on FreeBSD 11.2-RELEASE. On FreeBSD 11.1, it was easy to recompile only boot1 with the following commands: # cd /usr/src/sys/boot/efi/boot1 <apply patch> # make It compile fine and generate both boot1.efi & boot1.efifat binary. But on FreeBSD 11.2: # cd /usr/src/stand/efi/boot1 <apply patch> # make Killed. pid 1026 (make), uid 0, was killed: out of swap space The machine have 6 Gb of free memory before running make. Running make eat all available memory. How can I fix that ? What the best method to recompile only boot1.efi & boot1.efifat in a standalone way without recompile a full world ? Many thanks
(In reply to nicolas from comment #26) Hi, cd /usr/src/stand && make -j4 all in stable/11, after 11.1 but before 11.2. It still recompiles libsa and other bits, but the stand/ build is completely self-contained nowadays (assuming you have the proper toolchain to build for the target platform, of course. =))
Created attachment 201259 [details] boot1.c patch rev4 for stable/12 and head after r332751 Patch for head r332751 and later (before stable/12 branch). Forgot to upload for a long time. Applicable to both stable/12 and head, but would not to stable/11. (Not tested with stable/11.)
Created attachment 201260 [details] boot1.c patch rev4 for stable/11 after MFC of r332751 Updated patch for stable/11 after MFC of r332751. There were some not-MFC'ed changes on head, so different patch was needed. Not tested after stable/12 branch as I've moved to stable/12 ATM. If it does not apply, try patch for stable/12 and head.
stable/10 is EoL, cancel MFC request accordingly. Add requests for MFC to stable/{12,11} given we have specific proposed patches for those branches.
Created attachment 205099 [details] boot1.c + alpha patch rev4 for head after r348811 boot1.c + alpha patch rev4 for head after r348811. Newly introduced gptboot.efi is not supported. This is an ad-hoc patch and now we need nome other files to be patched because boot1.c is splitted into 2 .c and 1 .h files. Needless to say, we need massive cleanups *Use currently available helper functions instead of forcibly revived (deleted) old functions. *Re-implement to support gptboot.efi. before it can land, both of which I've not succeeded. Note: Currently breaking commit r348811 is not yet MFC'ed and having no MFC target.
Created attachment 205561 [details] boot1.c.stable12.diff I rewrite my patch for stable12.
Created attachment 205563 [details] proto.c.diff This is partition menu patch for head r348811. I put all modifications to proto.c file.
Created attachment 212457 [details] Patch for boot1.c and proto.c Thanks for coming back, Nomichi! And sorry for loooong delay. After your latest patch, *Now boot1.c includes getchar(), not compatible with the patch. *Now the same patch is applicable to latest head and stable/12. And unfortunately, it was difficult to determine the wanted partition if more than one FreeBSD with same partition No. and mostly the same size. This modified patch adds disk info in conjunction with partition No., and kills now-in-boot1.c version of getchar(). This should be applicable both head and stable/12 with some offsets or fuzzes. Ideally, disk and patrition info 100% matches just as running FreeBSD does like ada0p3, da1s1, but it's not implemented. Beware! NVMe drives would be shown up like drive(??), as proper DEVICE_PATH info is not yet defined on FreeBSD EFI implementation.
Created attachment 212647 [details] patch for head r350654 proto.c patch for head r350654 proto.c Thanks for AOKI-san for new patch. This is another way for identify partition. This patch shows partition raw uuid, which is shown in "gpart list".
boot1.efi is in the process of being deprecated...
(In reply to Warner Losh from comment #36) So What will happen ? move loader.efi to BCP ? use gptboot.efi ? or something totally new ?
(In reply to Naomichi Nonaka from comment #37) My understanding is that we use loader.efi directly.
What's the status of the patch for stable/13, 13.1-RELEASE branches ? Thanks.
(In reply to Nicolas from comment #39) At least the latest (Naomichi's) patch should be applicable with some offsets and builds/runs fine. As the patch was created against current (now called main after git transition) before stable/13 was branched, all 13.x should be OK. I always build world/kernel with the patch applied both on main and stable/13 (without committing locally, but `git stash`/`git stash apply` for every `git up`), and give the patched boot1.efi a try whether it's still working or not when some suspicious commits are done on src/stand/*.
Triage: * outdated flags * assign to kern@ ?
my preference is to put this functionality in loader.efi. boot1.efi is in the process of being deprecated because of the limited number of supported boot scenarios it can cover relative to loader.efi and that boot1.efi duplicates much of the selection process loader.efi does. However, gptboot.efi shows that there's a good case to be made for exceptions to the rule, and this might be OK until the functionality can be migrated to loader.efi.
(In reply to Warner Losh from comment #42) Glad to know the plan! Once it is completed, I have no objection to retire boot1.efi. I should mention that... *When selected non-default partition, boot should be done as if selected partition is the default partition. Currently, as boot1.efi kickes loader.efi and /boot/loader.conf is handled by loader.efi, this is naturally achieved. *If possible (I know it would be difficult), partitions would be better shown just as booted FreeBSD, like ada0s1, da2p5,... Maybe, nvd* and nda case would be impossible, as it depends on /boot/loader.conf settings. BTW, current default partition (pool) selection order is different between boot1.efi and loader.efi. Is this intentional? Current default boot1.efi behaves like 1. ZFS has always higher priority than UFS in the same physical drive. 2. First, sniff the drive UEFI loaded boot1.efi itself. 3. If neither ZFS pools nor UFS partitions have /boot/loader.conf, seek for next drive. 4. Drives are sniffed the order UEFI firmware finds. 5. Boot from first pool/partition found. The 1. seems to be different on loader.efi, IIUC. 1. would be because Non-Root-on-ZFS pool wouldn't have /boot/loader.efi and admins would want ZFS pool over UFS if installed as Root-on-ZFS.
Can't compile on FreeBSD 14.0: --- gptboot.sym.full --- cc -O2 -pipe -fno-common -I/usr/src/stand/efi/boot1 -I/usr/src/stand/efi/gptboot -DBOOTPROG=\"gptboot.efi\" -DHAVE_MEMCPY -I/usr/src/sys/contrib/zlib -Wformat -fshort-wchar -mno-red-zone -nostdinc -I/usr/obj/usr/src/amd64.amd64/stand/libsa -I/usr/src/stand/libsa -D_STANDALONE -I/usr/src/sys -Ddouble=jagged-little-pill -Dfloat=floaty-mcfloatface -ffunction-sections -fdata-sections -DLOADER_GELI_SUPPORT -I/usr/src/stand/libsa/geli -DLOADER_DISK_SUPPORT -ffreestanding -mno-mmx -mno-sse -mno-avx -mno-avx2 -msoft-float -fPIC -mno-red-zone -mno-relax -I. -Iinclude -DEFI_BOOT1 -I/usr/src/stand/efi/include -I/usr/src/stand/efi/include/amd64 -I/usr/src/sys/contrib/dev/acpica/include -DEFI_UFS_BOOT -DEFI_DEBUG -I/usr/src/stand/common -fPIC -g -gz=zlib -std=gnu99 -Wno-format-zero-length -Wsystem-headers -Werror -Wall -Wno-format-y2k -W -Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wunused-parameter -Wcast-align -Wchar-subscripts -Wnested-externs -Wold-style-definition -Wno-pointer-sign -Wdate-time -Wmissing-variable-declarations -Wthread-safety -Wno-empty-body -Wno-string-plus-int -Wno-unused-const-variable -Wno-error=unused-but-set-parameter -Oz -Qunused-arguments -nostdlib -Wl,-T/usr/src/stand/efi/loader/arch/amd64/ldscript.amd64,-Bsymbolic,-znotext -pie -Wl,-znocombreloc -Wl,-zrelro -o gptboot.sym.full gpt.o boot1.o proto.o self_reloc.o start.o ufs_module.o devpath.o /usr/obj/usr/src/amd64.amd64/stand/efi/libefi/libefi.a /usr/obj/usr/src/amd64.amd64/stand/libsa/libsa.a ld: error: undefined symbol: getchar >>> referenced by panic.c:48 (/usr/src/stand/libsa/panic.c:48) >>> panic.o:(panic_action) in archive /usr/obj/usr/src/amd64.amd64/stand/libsa/libsa.a cc: error: linker command failed with exit code 1 (use -v to see invocation) *** [gptboot.sym.full] Error code 1 make[2]: stopped in /usr/src/stand/efi/gptboot 1 error make[2]: stopped in /usr/src/stand/efi/gptboot make[1]: stopped in /usr/src/stand/efi --- all_subdir_efi/boot1 --- Both patch fully applied: 1. Patch for boot1.c and proto.c 2020-03-17 12:10 UTC, Tomoaki AOKI 2. patch for head r350654 proto.c 2020-03-23 16:02 UTC, Naomichi Nonaka (require manual application of the patch for the second part). Any idea on how to fix to make it works on FreeBSD 14.0 RELEASE ? Thanks
(In reply to Nicolas from comment #44) If you applied BOTH PATCHES AT ONCE, DO NOT DO SO. Choose whichebver you want, just one.
Created attachment 246766 [details] Patch for stable13 and later proto.c Patch for proto.c, stable/13 and later. This is a forgotten-to-upload patch after Nomichi Nonaka updated his patch. After my previous patch, *Copied Naomichi Nonaka's mygetchar() to proto.c and use it instead of getchar() to leave boot1.c untouched. This modified patch adds disk info in conjunction with partition No., instead of partition raw UUID used by Naomichi's latest patch. CHOOSE WHICHEVER YOU LIKE. DO NOT ATTEMPT TO APPLY BOTH AT ONCE! This should be applicable both head and stable/13 with some offsets or fuzzes. Ideally, disk and patrition info 100% matches just as running FreeBSD does like ada0p3, da1s1, but it's not implemented. Beware! NVMe drives would be shown up like drive(??), as proper DEVICE_PATH info is not yet defined on FreeBSD (U)EFI implementation.
I don't understand why the partition menu display using boot1.efifat (so FreeBSD 12 way) but not using boot1.efi + manual partition setup (so FreeBSD 13 and newer way). Since FreeBSD 13.0 and newer, boot1.efifat didn't exist anymore, so I use the following to write EFI partition of my disk: # newfs_msdos -F 12 -L EFISYS /dev/<phydevice>p1 ; # mount -t msdosfs /dev/<phydevice>p1 /mnt # mkdir -p /mnt/efi/boot # cp /boot/loader.efi /mnt/efi/boot/BOOTx64.efi # echo "BOOTx64.efi" > /mnt/efi/boot/startup.nsh # umount /mnt But the partition menu is not shown. I use the same newfs_msdos paramaters than https://cgit.freebsd.org/src/plain/stand/efi/boot1/generate-fat.sh?h=releng/12.3 used to create boot1.efifat. If I put /boot/boot1.efi from FreeBSD 14.0 into FreeBSD 12.3 system, the partition menu is shown. If I create manually a boot1.efifat on FreeBSD 14.0 (using FreeBSD 12 method from https://cgit.freebsd.org/src/plain/stand/efi/boot1/generate-fat.sh?h=releng/12.3 & https://cgit.freebsd.org/src/tree/stand/efi/boot1/Makefile?h=releng/12.3), partition menu works. mkdir /temp/boot1 cd /temp/boot1 dd if=/dev/zero of=fat-x64.tmpl bs=512 count=1600 mdconfig -a -f fat-x64.tmpl newfs_msdos -F 12 -L EFISYS md0 mkdir stub mount -t msdosfs /dev/md0 stub mkdir -p stub/efi/boot echo 'Boot1 START' | dd of=stub/efi/boot/BOOTx64.efi cbs=384k count=1 conv=block echo BOOTx64.efi > stub/efi/boot/startup.nsh umount stub mdconfig -d -u md0 rmdir stub xz -f fat-x64.tmpl xz -d -c fat-x64.tmpl.xz > boot1.efifat dd if=/boot/boot1.efi of=boot1.efifat seek=0x2d conv=notrunc cp boot1.efifat /boot/boot1.efifat dd if=/boot/boot1.efifat of=/dev/<phydevice>p1 ; Did you know how get the partition menu working on FreeBSD 14.0 without using boot1.efifat ?
https://man.freebsd.org/cgi/man.cgi?query=boot1.efi&apropos=0&sektion=8&manpath=FreeBSD+14.0-RELEASE&arch=default&format=html reports: QUOTE boot1.efi has been deprecated and will be removed from a future re- lease. loader.efi(8) handles all its former use cases with more flexi- bility. END QUOTE Adding new/adjusted functionality for 14.x+ to something deprecated for 14.x+ seems unlikely.
Sorry: the deprecated status was already covered by comment #42 ( And the page I referenced says it is from 13.2, so: 13.2+ .)
(In reply to Mark Millard from comment #48) Yes. So I (and maybe the original author, too) am maintaining patch here for anyone others who needs this functionality with best-effort basis until loader.efi gets equivalent (or even better) boot partition seceltion functionality. There's no assurance fot updating patches here, as it's not in-tree and updates are provided just a best-effort basis. For me, maintained src are latest stable branch (currently stable/14) and main only and no more considerations for older branches possible. I update my version of the patch (if possible, Naomich's one, too) only when... *build of boot1.efi somehow failes, or *even worse, `git stash && git pull --ff-only && git stash apply` failed on /usr/src/stand/*. Once loader.efi comes to get functionality to boot FreeBSD on any partition on any drive and treat the actual boot partition/drive as primary (use loader.conf etc. there), I'll stop maintaining my patch here. But it doesn't yet happened. I had no objection for DEPRECATING boot1.efi, and actually deprecated, but unless loader.efi get the functionality, I strongly object for DELETION of boot1.efi sources.