Message ID | 20220428080950.23509-1-masahisa.kojima@linaro.org |
---|---|
Headers | show |
Series | enable menu-driven boot device selection | expand |
On 4/28/22 10:09, Masahisa Kojima wrote: > This patch series adds the menu-driven boot device selection, > by extending the existing "bootmenu" to include UEFI and distro_boot > related entries, and supports menu-driven UEFI boot variable > maintenance. > > This patch series also includes the removable media support > that UEFI specification requires to support. > > The menu example is as follows. > > *** U-Boot Boot Menu *** > > bootmenu_00 : Boot 1. kernel > bootmenu_01 : Boot 2. kernel > bootmenu_02 : Reset board > UEFI BOOT0000 : debian > UEFI BOOT0001 : ubuntu > UEFI BOOT0002 : mmc0:1 > UEFI BOOT0003 : mmc0:2 > UEFI BOOT0004 : nvme0:1 > UEFI BOOT0005 : nvme0:2 > UEFI BOOT0006 : usb0:2 > UEFI BOOT0007 : usb1:1 > UEFI BOOT0008 : usb1:2 > distro_boot : usb0 > distro_boot : scsi0 > distro_boot : virtio0 > distro_boot : dhcp > > Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit > > [How to run on QEMU(arm64)] > 1) clone source code > $ git clone https://git.linaro.org/people/masahisa.kojima/u-boot.git \ > -b kojima/bootmenu_v5_upstream_0428 --depth 1 > > 2) prepare U-Boot .config > $ make qemu_arm64_menuconfig > then, enable CONFIG_CMD_BOOTMENU and CONFIG_AUTOBOOT_MENU_SHOW > > 3) run on QEMU(arm64) example > $ qemu-system-aarch64 -machine virt,gic-version=3 -cpu cortex-a57 -m 4G -nographic \ > -no-acpi -bios ./u-boot.bin -hda xxx.img > > [Major Changes] > - rebased to v2022.07-rc1 > - there is detailed changelog in each commit > > AKASHI Takahiro (2): > efi_loader: export efi_locate_device_handle() > efi_loader: bootmgr: add booting from removable media > > Masahisa Kojima (15): > lib/charset: add u16_strlcat() function > test: unit test for u16_strlcat() > menu: always show the menu regardless of the number of entry > menu: menu_get_choice() return -ENOENT if menu item is empty > bootmenu: flush input buffer before waiting user key input > bootmenu: update bootmenu_entry structure > bootmenu: add UEFI boot entry into bootmenu > bootmenu: add distro boot entry > bootmenu: add Kconfig option not to enter U-Boot console > bootmenu: factor out the user input handling > efi_loader: menu-driven addition of UEFI boot option > efi_loader: menu-driven deletion of UEFI boot variable > efi_loader: menu-driven update of UEFI bootorder variable > bootmenu: add removable media entries > doc:bootmenu: add UEFI boot and distro boot support description > > cmd/Kconfig | 10 + > cmd/bootmenu.c | 807 +++++++++---- > common/menu.c | 142 ++- > doc/usage/cmd/bootmenu.rst | 78 +- > include/charset.h | 17 + > include/config_distro_bootcmd.h | 14 +- > include/efi_default_filename.h | 33 + > include/efi_loader.h | 61 + > include/menu.h | 20 + > lib/charset.c | 22 + > lib/efi_loader/Makefile | 1 + > lib/efi_loader/efi_bootmenu_maintenance.c | 1245 +++++++++++++++++++++ > lib/efi_loader/efi_bootmgr.c | 50 +- > lib/efi_loader/efi_boottime.c | 59 +- > lib/efi_loader/efi_console.c | 81 ++ > lib/efi_loader/efi_disk.c | 11 + > lib/efi_loader/efi_file.c | 75 +- > test/unicode_ut.c | 50 + > 18 files changed, 2518 insertions(+), 258 deletions(-) > create mode 100644 include/efi_default_filename.h > create mode 100644 lib/efi_loader/efi_bootmenu_maintenance.c > I prepared my test as follows: make sandbox_defconfig CONFIG_CMD_BOOTMENU=y CONFIG_AUTOBOOT_MENU_SHOW=y PREBOOT=host bind 0 ../sandbox.img I created ../sandbox.img as GTP partioned image with a single EF00 partition. Onto the partition I copied lib/efi_loader/helloworld.efi into path EFI/BOOT/BOOTX64.EFI. I set up the following boot option: => efidebug boot dump Boot0001: attributes: A-- (0x00000001) label: hello host 0:1 file_path: /HD(1,GPT,7e5c17c5-3f5f-49d0-ae96-511b21d7f273,0x800,0x3f7df)/EFI\BOOT\BOOTX64.EFI data: 00000000: 6d 00 79 00 20 00 6d 00 65 00 73 00 73 00 61 00 m.y. .m.e.s.s.a. 00000010: 67 00 65 00 00 00 g.e... => efidebug boot order 1: Boot0001: hello host 0:1 => reset Now the boot menu looks like this: *** U-Boot Boot Menu *** UEFI BOOT0001 : hello host 0:1 UEFI BOOT0000 : host0:1 UEFI Boot Manager Maintenance U-Boot console When I select nothing: try_load_entry: trying to load "hello host 0:1" from /HD(1,GPT,7e5c17c5-3f5f-49d0-ae96-511b21d7f273,0x800,0x3f7df)/EFI\BOOT\BOOTX64.EFI Booting: hello host 0:1 Hello, world! Running on UEFI 2.9 Have ACPI 2.0 table Have SMBIOS table Load options: my message Boot device: /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/VenHw(bbe4e671-5773-4ea1-9aab-3a7dbf40c482,00)/HD(1,GPT,7e5c17c5-3f5f-49d0-ae96-511b21d7f273,0x800,0x3f7df) File path: /EFI\BOOT\BOOTX64.EFI This is ok. *** U-Boot Boot Menu *** UEFI BOOT0001 : hello host 0:1 UEFI BOOT0000 : host0:1 UEFI Boot Manager Maintenance U-Boot console Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit When I select the second item 'UEFI BOOT0000 : host0:1': try_load_entry: trying to load "host0:1" from /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/VenHw(bbe4e671-5773-4ea1-9aab-3a7dbf40c482,00)/HD(1,GPT,7e5c17c5-3f5f-49d0-ae96-511b21d7f273,0x800,0x3f7df) Loading Boot0000 'host0:1' failed After I fixed this in [PATCH 1/1] efi_loader: BOOTSANDBOX.EFI is not a default file name https://lists.denx.de/pipermail/u-boot/2022-April/482763.html Booting: host 0:1 Hello, world! Running on UEFI 2.9 Have ACPI 2.0 table Have SMBIOS table Load options: 곁㣁鿀䇰ƹ瓺훖? Boot device: /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/VenHw(bbe4e671-5773-4ea1-9aab-3a7dbf40c482,00)/HD(1,GPT,7e5c17c5-3f5f-49d0-ae96-511b21d7f273,0x800,0x3f7df) File path: /\EFI\BOOT\BOOTX64.EFI See those Chinese letters. Something is going really wrong here. Best regards Heinrich
On 4/28/22 18:31, Heinrich Schuchardt wrote: > On 4/28/22 10:09, Masahisa Kojima wrote: >> This patch series adds the menu-driven boot device selection, >> by extending the existing "bootmenu" to include UEFI and distro_boot >> related entries, and supports menu-driven UEFI boot variable >> maintenance. >> >> This patch series also includes the removable media support >> that UEFI specification requires to support. >> >> The menu example is as follows. >> >> *** U-Boot Boot Menu *** >> >> bootmenu_00 : Boot 1. kernel >> bootmenu_01 : Boot 2. kernel >> bootmenu_02 : Reset board >> UEFI BOOT0000 : debian >> UEFI BOOT0001 : ubuntu >> UEFI BOOT0002 : mmc0:1 >> UEFI BOOT0003 : mmc0:2 >> UEFI BOOT0004 : nvme0:1 >> UEFI BOOT0005 : nvme0:2 >> UEFI BOOT0006 : usb0:2 >> UEFI BOOT0007 : usb1:1 >> UEFI BOOT0008 : usb1:2 >> distro_boot : usb0 >> distro_boot : scsi0 >> distro_boot : virtio0 >> distro_boot : dhcp >> >> Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit >> >> [How to run on QEMU(arm64)] >> 1) clone source code >> $ git clone https://git.linaro.org/people/masahisa.kojima/u-boot.git \ >> -b kojima/bootmenu_v5_upstream_0428 --depth 1 >> >> 2) prepare U-Boot .config >> $ make qemu_arm64_menuconfig >> then, enable CONFIG_CMD_BOOTMENU and CONFIG_AUTOBOOT_MENU_SHOW >> >> 3) run on QEMU(arm64) example >> $ qemu-system-aarch64 -machine virt,gic-version=3 -cpu cortex-a57 -m >> 4G -nographic \ >> -no-acpi -bios ./u-boot.bin -hda xxx.img >> >> [Major Changes] >> - rebased to v2022.07-rc1 >> - there is detailed changelog in each commit >> >> AKASHI Takahiro (2): >> efi_loader: export efi_locate_device_handle() >> efi_loader: bootmgr: add booting from removable media >> >> Masahisa Kojima (15): >> lib/charset: add u16_strlcat() function >> test: unit test for u16_strlcat() >> menu: always show the menu regardless of the number of entry >> menu: menu_get_choice() return -ENOENT if menu item is empty >> bootmenu: flush input buffer before waiting user key input >> bootmenu: update bootmenu_entry structure >> bootmenu: add UEFI boot entry into bootmenu >> bootmenu: add distro boot entry >> bootmenu: add Kconfig option not to enter U-Boot console >> bootmenu: factor out the user input handling >> efi_loader: menu-driven addition of UEFI boot option >> efi_loader: menu-driven deletion of UEFI boot variable >> efi_loader: menu-driven update of UEFI bootorder variable >> bootmenu: add removable media entries >> doc:bootmenu: add UEFI boot and distro boot support description >> >> cmd/Kconfig | 10 + >> cmd/bootmenu.c | 807 +++++++++---- >> common/menu.c | 142 ++- >> doc/usage/cmd/bootmenu.rst | 78 +- >> include/charset.h | 17 + >> include/config_distro_bootcmd.h | 14 +- >> include/efi_default_filename.h | 33 + >> include/efi_loader.h | 61 + >> include/menu.h | 20 + >> lib/charset.c | 22 + >> lib/efi_loader/Makefile | 1 + >> lib/efi_loader/efi_bootmenu_maintenance.c | 1245 +++++++++++++++++++++ >> lib/efi_loader/efi_bootmgr.c | 50 +- >> lib/efi_loader/efi_boottime.c | 59 +- >> lib/efi_loader/efi_console.c | 81 ++ >> lib/efi_loader/efi_disk.c | 11 + >> lib/efi_loader/efi_file.c | 75 +- >> test/unicode_ut.c | 50 + >> 18 files changed, 2518 insertions(+), 258 deletions(-) >> create mode 100644 include/efi_default_filename.h >> create mode 100644 lib/efi_loader/efi_bootmenu_maintenance.c >> > > I prepared my test as follows: > > make sandbox_defconfig > CONFIG_CMD_BOOTMENU=y > CONFIG_AUTOBOOT_MENU_SHOW=y > PREBOOT=host bind 0 ../sandbox.img > > I created ../sandbox.img as GTP partioned image with a single EF00 > partition. Onto the partition I copied lib/efi_loader/helloworld.efi > into path EFI/BOOT/BOOTX64.EFI. > > I set up the following boot option: > > => efidebug boot dump > Boot0001: > attributes: A-- (0x00000001) > label: hello host 0:1 > file_path: > /HD(1,GPT,7e5c17c5-3f5f-49d0-ae96-511b21d7f273,0x800,0x3f7df)/EFI\BOOT\BOOTX64.EFI > > data: > 00000000: 6d 00 79 00 20 00 6d 00 65 00 73 00 73 00 61 00 m.y. > .m.e.s.s.a. > 00000010: 67 00 65 00 00 00 g.e... > => efidebug boot order > 1: Boot0001: hello host 0:1 > => reset > > Now the boot menu looks like this: > > *** U-Boot Boot Menu *** > > UEFI BOOT0001 : hello host 0:1 > UEFI BOOT0000 : host0:1 > UEFI Boot Manager Maintenance > U-Boot console > > When I select nothing: > > try_load_entry: trying to load "hello host 0:1" from > /HD(1,GPT,7e5c17c5-3f5f-49d0-ae96-511b21d7f273,0x800,0x3f7df)/EFI\BOOT\BOOTX64.EFI > > Booting: hello host 0:1 > Hello, world! > Running on UEFI 2.9 > Have ACPI 2.0 table > Have SMBIOS table > Load options: my message > Boot device: > /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/VenHw(bbe4e671-5773-4ea1-9aab-3a7dbf40c482,00)/HD(1,GPT,7e5c17c5-3f5f-49d0-ae96-511b21d7f273,0x800,0x3f7df) > > File path: /EFI\BOOT\BOOTX64.EFI > > This is ok. > > *** U-Boot Boot Menu *** > > UEFI BOOT0001 : hello host 0:1 > UEFI BOOT0000 : host0:1 > UEFI Boot Manager Maintenance > U-Boot console > > > Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit > > When I select the second item 'UEFI BOOT0000 : host0:1': > > try_load_entry: trying to load "host0:1" from > /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/VenHw(bbe4e671-5773-4ea1-9aab-3a7dbf40c482,00)/HD(1,GPT,7e5c17c5-3f5f-49d0-ae96-511b21d7f273,0x800,0x3f7df) > > Loading Boot0000 'host0:1' failed > > After I fixed this in > [PATCH 1/1] efi_loader: BOOTSANDBOX.EFI is not a default file name > https://lists.denx.de/pipermail/u-boot/2022-April/482763.html > > Booting: host 0:1 > Hello, world! > Running on UEFI 2.9 > Have ACPI 2.0 table > Have SMBIOS table > Load options: 곁㣁鿀䇰ƹ瓺훖? After converting to hex: acc1 38c1 9fc0 41f0 01b9 74fa d6d6 dee4 This is just your GUID: #define EFI_BOOTMENU_AUTO_GENERATED_ENTRY_GUID \ EFI_GUID(0x38c1acc1, 0x9fc0, 0x41f0, \ 0xb9, 0x01, 0xfa, 0x74, 0xd6, 0xd6, 0xe4, 0xde) You need to remove it from the load option. Best regards Heinrich > Boot device: > /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/VenHw(bbe4e671-5773-4ea1-9aab-3a7dbf40c482,00)/HD(1,GPT,7e5c17c5-3f5f-49d0-ae96-511b21d7f273,0x800,0x3f7df) > > File path: /\EFI\BOOT\BOOTX64.EFI > > See those Chinese letters. Something is going really wrong here. > > Best regards > > Heinrich > > > > > > >
> From: Masahisa Kojima <masahisa.kojima@linaro.org> > Date: Thu, 28 Apr 2022 17:09:33 +0900 > > This patch series adds the menu-driven boot device selection, > by extending the existing "bootmenu" to include UEFI and distro_boot > related entries, and supports menu-driven UEFI boot variable > maintenance. > > This patch series also includes the removable media support > that UEFI specification requires to support. > > The menu example is as follows. > > *** U-Boot Boot Menu *** > > bootmenu_00 : Boot 1. kernel > bootmenu_01 : Boot 2. kernel > bootmenu_02 : Reset board > UEFI BOOT0000 : debian > UEFI BOOT0001 : ubuntu > UEFI BOOT0002 : mmc0:1 > UEFI BOOT0003 : mmc0:2 > UEFI BOOT0004 : nvme0:1 > UEFI BOOT0005 : nvme0:2 > UEFI BOOT0006 : usb0:2 > UEFI BOOT0007 : usb1:1 > UEFI BOOT0008 : usb1:2 > distro_boot : usb0 > distro_boot : scsi0 > distro_boot : virtio0 > distro_boot : dhcp > > Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit > > [How to run on QEMU(arm64)] > 1) clone source code > $ git clone https://git.linaro.org/people/masahisa.kojima/u-boot.git \ > -b kojima/bootmenu_v5_upstream_0428 --depth 1 > > 2) prepare U-Boot .config > $ make qemu_arm64_menuconfig > then, enable CONFIG_CMD_BOOTMENU and CONFIG_AUTOBOOT_MENU_SHOW So when I do this on a Apple M1 system it ends up doing something weird. With CONFIG_AUTOBOOT_MENU_SHOW=y, it shows the boot menu and then automaticaly selects the "UEFI Boot Manager Maintenance" option after the boot delay expires. That is a bit weird. Initially I expected it to fall through into the normal distro_bootcmd script by executing bootcmd. Now this happens because NVMe isn't probed automatically. So no viable boot options are found. But distro_boot explicitly probes NVMe if CONFIG_NVME is enabled (see include/config_distro_bootcmd.h). So falling through into the distro boot would actually have worked. Another surprise is that the default boot order seems to depend on the order in which devices are probed. With: CONFIG_PREBOOT="nvme scan; usb start" it boots from NVMe by default, and with: CONFIG_PREBOOT="usb start; nvme scan" it boots from USB by default, despite the fact that in include/configs/apple.h I have: #define BOOT_TARGET_DEVICES(func) \ BOOT_TARGET_NVME(func) \ BOOT_TARGET_USB(func) If I change the boot order through the "UEFI Boot Manager Maintenance" option, it seems that the new boot order only persists if I actually boot into the OS. When I reset the board before doing that it keeps the old boot order. Last but not least, it seems that CONFIG_CMD_BOOTMENU_ENTER_UBOOT_CONSOLE is disabled by default despite the fact that doc/usage/cmd/bootmenu.rst suggests the opposite. I think the default for that option should be "y" otherwise I fear a lot of boards will end up with shipping with a U-Boot with no way for users to get at the u-boot prompt. All in all, I don't think any of this is a show-stopper. It just needs some further polishing, which probably is best done after this lands (except for the CMD_BOOTMENU_ENTER_UBOOT_CONSOLE thing). It does make it possible for me to use the EFI bootmgr on Apple M1 systems and it definitely improves the user interface for naive users.