Skip to contentSkip to conversation

efi_loader: improve boot sequence in distro_bootcmd

PATCH Superseded AKASHI Takahiro 3 participants 10 messages Oct 22, 2018 – Oct 24, 2018

Subsystems (2)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

v2 cover efi_loader: improve boot sequence in distro_bootcmd

The current distro_bootcmd has several issues regarding efi boot. (See the patch#1 for details.)

Patch#1: fix distro's issues and make its intent clear Patch#2,#3: address related issues on qemu-arm

Please note that patch#2 is now rebased on Bin's patch[1].

[1] https://lists.denx.de/pipermail/u-boot/2018-October/344421.html

Changes in v2 (Oct 22, 2018):
* rewrite my previous changes after Alex's comments, including
- boot bootmgr only once before searching for boot binary
- dtb must be loaded from the same device with boot binary's
* add patch#2 as part of this patch set, in particular adding CONFIG_SYS

Thanks,
-Takahio Akashi

AKASHI Takahiro (3):
efi_loader: rework fdt handling in distro boot script
ARM: qemu-arm: rework Kconfig
ARM: qemu-arm: define fdt_addr_r

 arch/arm/mach-qemu/Kconfig       | 18 ++++++++-------
 board/emulation/qemu-arm/Kconfig |  6 +++++
 include/config_distro_bootcmd.h  | 38 +++++++++++++++++---------------
 include/configs/qemu-arm.h       |  1 +
 4 files changed, 37 insertions(+), 26 deletions(-)
Signature · 1 line
2.19.0
#1 lore raw

PATCH v2 1/3 efi_loader: rework fdt handling in distro boot script

The current scenario for default UEFI booting, scan_dev_for_efi, has several issues:
* load dtb dynamically even if its loacation (device) is not the same as BOOTEFI_NAME binary's, (reported by Alex)
* invoke 'bootmgr' only if BOOTEFI_NAME binary does exit even though 'bootmgr' can and should work independently whether or not the binary exist,
* in addition, invoke 'bootmgr' with dynamically-loaded dtb.
This behavior is not expected. (reported by Alex)
* always assume that a 'fdtfile' variable is defined,
("test -e ${devtype} ${devnum}:${distro_bootpart} "${prefix}${efi_fdtfile}" always returns true even if fdtfile is NULL with prefix=="/".)
* redundantly check for 'fdt_addr_r' in boot_efi_binary

In this patch, all the issues above are sorted out.
Please note that the default behavior can be customized with:
fdtfile: a dtb file name
efi_dtb_prefixes: a list of paths for searching for a dtb file

(this feature does work even without this patch.)

---
 include/config_distro_bootcmd.h | 38 +++++++++++++++++----------------
 1 file changed, 20 insertions(+), 18 deletions(-)
include/config_distro_bootcmd.h +20 -18
index 373fee78a999..256698309eb9 100644
@@ -115,7 +115,7 @@
  */
 #define BOOTENV_EFI_SET_FDTFILE_FALLBACK                                  \
 	"if test -z \"${fdtfile}\" -a -n \"${soc}\"; then "               \
-	  "setenv efi_fdtfile ${soc}-${board}${boardver}.dtb; "           \
+	  "efi_fdtfile=${soc}-${board}${boardver}.dtb; "           \
 	"fi; "
 #else
 #define BOOTENV_EFI_SET_FDTFILE_FALLBACK
@@ -124,26 +124,20 @@
 
 #define BOOTENV_SHARED_EFI                                                \
 	"boot_efi_binary="                                                \
-		"if fdt addr ${fdt_addr_r}; then "                        \
-			"bootefi bootmgr ${fdt_addr_r};"                  \
-		"else "                                                   \
-			"bootefi bootmgr ${fdtcontroladdr};"              \
-		"fi;"                                                     \
 		"load ${devtype} ${devnum}:${distro_bootpart} "           \
 			"${kernel_addr_r} efi/boot/"BOOTEFI_NAME"; "      \
-		"if fdt addr ${fdt_addr_r}; then "                        \
-			"bootefi ${kernel_addr_r} ${fdt_addr_r};"         \
-		"else "                                                   \
-			"bootefi ${kernel_addr_r} ${fdtcontroladdr};"     \
-		"fi\0"                                                    \
+		"bootefi ${kernel_addr_r} ${efi_fdt_addr};\0"		  \
 	\
 	"load_efi_dtb="                                                   \
-		"load ${devtype} ${devnum}:${distro_bootpart} "           \
-			"${fdt_addr_r} ${prefix}${efi_fdtfile}\0"         \
+		"load ${devtype} ${devnum}:${distro_bootpart} "		  \
+			"${fdt_addr_r} ${prefix}${efi_fdtfile}; "	  \
+		"if fdt addr ${fdt_addr_r}; then "			  \
+			"efi_fdt_addr=${fdt_addr_r}; "			  \
+		"fi;\0"							  \
 	\
 	"efi_dtb_prefixes=/ /dtb/ /dtb/current/\0"                        \
-	"scan_dev_for_efi="                                               \
-		"setenv efi_fdtfile ${fdtfile}; "                         \
+	"set_efi_fdt_addr="						  \
+		"efi_fdtfile=${fdtfile}; "                         \
 		BOOTENV_EFI_SET_FDTFILE_FALLBACK                          \
 		"for prefix in ${efi_dtb_prefixes}; do "                  \
 			"if test -e ${devtype} "                          \
@@ -151,19 +145,26 @@
 					"${prefix}${efi_fdtfile}; then "  \
 				"run load_efi_dtb; "                      \
 			"fi;"                                             \
-		"done;"                                                   \
+		"done;\0"                                                   \
+	\
+	"scan_dev_for_efi="                                               \
 		"if test -e ${devtype} ${devnum}:${distro_bootpart} "     \
 					"efi/boot/"BOOTEFI_NAME"; then "  \
 				"echo Found EFI removable media binary "  \
 					"efi/boot/"BOOTEFI_NAME"; "       \
+				"efi_fdt_addr=${fdtcontroladdr}; "	  \
+				"if test -n \"${fdtfile}\"; then "	  \
+					"run set_efi_fdt_addr; "	  \
+				"fi; "					  \
 				"run boot_efi_binary; "                   \
 				"echo EFI LOAD FAILED: continuing...; "   \
-		"fi; "                                                    \
-		"setenv efi_fdtfile\0"
+		"fi;\0"
 #define SCAN_DEV_FOR_EFI "run scan_dev_for_efi;"
+#define BOOT_EFI_BOOT_MANAGER "bootefi bootmgr;"
 #else
 #define BOOTENV_SHARED_EFI
 #define SCAN_DEV_FOR_EFI
+#define BOOT_EFI_BOOT_MANAGER
 #endif
 
 #ifdef CONFIG_SATA
@@ -409,6 +410,7 @@
 	BOOT_TARGET_DEVICES(BOOTENV_DEV)                                  \
 	\
 	"distro_bootcmd=" BOOTENV_SET_SCSI_NEED_INIT                      \
+		BOOT_EFI_BOOT_MANAGER					  \
 		"for target in ${boot_targets}; do "                      \
 			"run bootcmd_${target}; "                         \
 		"done\0"
Signature · 1 line
2.19.0
#2 lore raw

PATCH v2 1/3 efi_loader: rework fdt handling in distro boot script

Quoted 105 lines · AKASHI Takahiro

The current scenario for default UEFI booting, scan_dev_for_efi, has several issues:
* load dtb dynamically even if its loacation (device) is not the same as BOOTEFI_NAME binary's, (reported by Alex)
* invoke 'bootmgr' only if BOOTEFI_NAME binary does exit even though 'bootmgr' can and should work independently whether or not the binary exist,
* in addition, invoke 'bootmgr' with dynamically-loaded dtb.
This behavior is not expected. (reported by Alex)
* always assume that a 'fdtfile' variable is defined,
("test -e ${devtype} ${devnum}:${distro_bootpart} "${prefix}${efi_fdtfile}" always returns true even if fdtfile is NULL with prefix=="/".)
* redundantly check for 'fdt_addr_r' in boot_efi_binary

In this patch, all the issues above are sorted out.
Please note that the default behavior can be customized with:
fdtfile: a dtb file name
efi_dtb_prefixes: a list of paths for searching for a dtb file

(this feature does work even without this patch.)

---
 include/config_distro_bootcmd.h | 38 +++++++++++++++++----------------
 1 file changed, 20 insertions(+), 18 deletions(-)
include/config_distro_bootcmd.h +19 -18
index 373fee78a999..256698309eb9 100644
@@ -115,7 +115,7 @@
  */
 #define BOOTENV_EFI_SET_FDTFILE_FALLBACK                                  \
 	"if test -z \"${fdtfile}\" -a -n \"${soc}\"; then "               \
-	  "setenv efi_fdtfile ${soc}-${board}${boardver}.dtb; "           \
+	  "efi_fdtfile=${soc}-${board}${boardver}.dtb; "           \
 	"fi; "
 #else
 #define BOOTENV_EFI_SET_FDTFILE_FALLBACK
@@ -124,26 +124,20 @@
 
 #define BOOTENV_SHARED_EFI                                                \
 	"boot_efi_binary="                                                \
-		"if fdt addr ${fdt_addr_r}; then "                        \
-			"bootefi bootmgr ${fdt_addr_r};"                  \
-		"else "                                                   \
-			"bootefi bootmgr ${fdtcontroladdr};"              \
-		"fi;"                                                     \
 		"load ${devtype} ${devnum}:${distro_bootpart} "           \
 			"${kernel_addr_r} efi/boot/"BOOTEFI_NAME"; "      \
-		"if fdt addr ${fdt_addr_r}; then "                        \
-			"bootefi ${kernel_addr_r} ${fdt_addr_r};"         \
-		"else "                                                   \
-			"bootefi ${kernel_addr_r} ${fdtcontroladdr};"     \
-		"fi\0"                                                    \
+		"bootefi ${kernel_addr_r} ${efi_fdt_addr};\0"		  \
 	\
 	"load_efi_dtb="                                                   \
-		"load ${devtype} ${devnum}:${distro_bootpart} "           \
-			"${fdt_addr_r} ${prefix}${efi_fdtfile}\0"         \
+		"load ${devtype} ${devnum}:${distro_bootpart} "		  \
+			"${fdt_addr_r} ${prefix}${efi_fdtfile}; "	  \
+		"if fdt addr ${fdt_addr_r}; then "			  \
+			"efi_fdt_addr=${fdt_addr_r}; "			  \
+		"fi;\0"							  \
 	\
 	"efi_dtb_prefixes=/ /dtb/ /dtb/current/\0"                        \
-	"scan_dev_for_efi="                                               \
-		"setenv efi_fdtfile ${fdtfile}; "                         \
+	"set_efi_fdt_addr="						  \
+		"efi_fdtfile=${fdtfile}; "                         \
 		BOOTENV_EFI_SET_FDTFILE_FALLBACK                          \
 		"for prefix in ${efi_dtb_prefixes}; do "                  \
 			"if test -e ${devtype} "                          \
@@ -151,19 +145,26 @@
 					"${prefix}${efi_fdtfile}; then "  \
 				"run load_efi_dtb; "                      \
 			"fi;"                                             \
-		"done;"                                                   \
+		"done;\0"                                                   \
+	\
+	"scan_dev_for_efi="                                               \
 		"if test -e ${devtype} ${devnum}:${distro_bootpart} "     \
 					"efi/boot/"BOOTEFI_NAME"; then "  \
 				"echo Found EFI removable media binary "  \
 					"efi/boot/"BOOTEFI_NAME"; "       \
+				"efi_fdt_addr=${fdtcontroladdr}; "	  \
+				"if test -n \"${fdtfile}\"; then "	  \
+					"run set_efi_fdt_addr; "	  \
+				"fi; "					  \
 				"run boot_efi_binary; "                   \
 				"echo EFI LOAD FAILED: continuing...; "   \
-		"fi; "                                                    \
-		"setenv efi_fdtfile\0"
+		"fi;\0"
 #define SCAN_DEV_FOR_EFI "run scan_dev_for_efi;"
+#define BOOT_EFI_BOOT_MANAGER "bootefi bootmgr;"
 #else
 #define BOOTENV_SHARED_EFI
 #define SCAN_DEV_FOR_EFI
+#define BOOT_EFI_BOOT_MANAGER
 #endif
 
 #ifdef CONFIG_SATA

include/config_distro_bootcmd.h line 413

Quoted 4 lines
include/config_distro_bootcmd.h +1 -0
@@ -409,6 +410,7 @@
 	BOOT_TARGET_DEVICES(BOOTENV_DEV)                                  \
 	\
 	"distro_bootcmd=" BOOTENV_SET_SCSI_NEED_INIT                      \
+		BOOT_EFI_BOOT_MANAGER					  \

The last-minute change may have introduced a problem. By moving "bootmgr" from scan_dev_for_efi" to here, grub fails to start a grub.cfg menu, saying
"error: no such device: /.disk/info."

Do you have any ideas?

-Takahiro Akashi

Quoted 6 lines
include/config_distro_bootcmd.h +0 -0
 		"for target in ${boot_targets}; do "                      \
 			"run bootcmd_${target}; "                         \
 		"done\0"
Signature · 1 line
2.19.0
#3 lore raw

PATCH v2 1/3 efi_loader: rework fdt handling in distro boot script

Quoted 116 lines · AKASHI Takahiro
Quoted 105 lines · AKASHI Takahiro

The current scenario for default UEFI booting, scan_dev_for_efi, has several issues:
* load dtb dynamically even if its loacation (device) is not the same as BOOTEFI_NAME binary's, (reported by Alex)
* invoke 'bootmgr' only if BOOTEFI_NAME binary does exit even though 'bootmgr' can and should work independently whether or not the binary exist,
* in addition, invoke 'bootmgr' with dynamically-loaded dtb.
This behavior is not expected. (reported by Alex)
* always assume that a 'fdtfile' variable is defined,
("test -e ${devtype} ${devnum}:${distro_bootpart} "${prefix}${efi_fdtfile}" always returns true even if fdtfile is NULL with prefix=="/".)
* redundantly check for 'fdt_addr_r' in boot_efi_binary

In this patch, all the issues above are sorted out.
Please note that the default behavior can be customized with:
fdtfile: a dtb file name
efi_dtb_prefixes: a list of paths for searching for a dtb file

(this feature does work even without this patch.)

---
 include/config_distro_bootcmd.h | 38 +++++++++++++++++----------------
 1 file changed, 20 insertions(+), 18 deletions(-)
include/config_distro_bootcmd.h +19 -18
index 373fee78a999..256698309eb9 100644
@@ -115,7 +115,7 @@
  */
 #define BOOTENV_EFI_SET_FDTFILE_FALLBACK                                  \
 	"if test -z \"${fdtfile}\" -a -n \"${soc}\"; then "               \
-	  "setenv efi_fdtfile ${soc}-${board}${boardver}.dtb; "           \
+	  "efi_fdtfile=${soc}-${board}${boardver}.dtb; "           \
 	"fi; "
 #else
 #define BOOTENV_EFI_SET_FDTFILE_FALLBACK
@@ -124,26 +124,20 @@
 
 #define BOOTENV_SHARED_EFI                                                \
 	"boot_efi_binary="                                                \
-		"if fdt addr ${fdt_addr_r}; then "                        \
-			"bootefi bootmgr ${fdt_addr_r};"                  \
-		"else "                                                   \
-			"bootefi bootmgr ${fdtcontroladdr};"              \
-		"fi;"                                                     \
 		"load ${devtype} ${devnum}:${distro_bootpart} "           \
 			"${kernel_addr_r} efi/boot/"BOOTEFI_NAME"; "      \
-		"if fdt addr ${fdt_addr_r}; then "                        \
-			"bootefi ${kernel_addr_r} ${fdt_addr_r};"         \
-		"else "                                                   \
-			"bootefi ${kernel_addr_r} ${fdtcontroladdr};"     \
-		"fi\0"                                                    \
+		"bootefi ${kernel_addr_r} ${efi_fdt_addr};\0"		  \
 	\
 	"load_efi_dtb="                                                   \
-		"load ${devtype} ${devnum}:${distro_bootpart} "           \
-			"${fdt_addr_r} ${prefix}${efi_fdtfile}\0"         \
+		"load ${devtype} ${devnum}:${distro_bootpart} "		  \
+			"${fdt_addr_r} ${prefix}${efi_fdtfile}; "	  \
+		"if fdt addr ${fdt_addr_r}; then "			  \
+			"efi_fdt_addr=${fdt_addr_r}; "			  \
+		"fi;\0"							  \
 	\
 	"efi_dtb_prefixes=/ /dtb/ /dtb/current/\0"                        \
-	"scan_dev_for_efi="                                               \
-		"setenv efi_fdtfile ${fdtfile}; "                         \
+	"set_efi_fdt_addr="						  \
+		"efi_fdtfile=${fdtfile}; "                         \
 		BOOTENV_EFI_SET_FDTFILE_FALLBACK                          \
 		"for prefix in ${efi_dtb_prefixes}; do "                  \
 			"if test -e ${devtype} "                          \
@@ -151,19 +145,26 @@
 					"${prefix}${efi_fdtfile}; then "  \
 				"run load_efi_dtb; "                      \
 			"fi;"                                             \
-		"done;"                                                   \
+		"done;\0"                                                   \
+	\
+	"scan_dev_for_efi="                                               \
 		"if test -e ${devtype} ${devnum}:${distro_bootpart} "     \
 					"efi/boot/"BOOTEFI_NAME"; then "  \
 				"echo Found EFI removable media binary "  \
 					"efi/boot/"BOOTEFI_NAME"; "       \
+				"efi_fdt_addr=${fdtcontroladdr}; "	  \
+				"if test -n \"${fdtfile}\"; then "	  \
+					"run set_efi_fdt_addr; "	  \
+				"fi; "					  \
 				"run boot_efi_binary; "                   \
 				"echo EFI LOAD FAILED: continuing...; "   \
-		"fi; "                                                    \
-		"setenv efi_fdtfile\0"
+		"fi;\0"
 #define SCAN_DEV_FOR_EFI "run scan_dev_for_efi;"
+#define BOOT_EFI_BOOT_MANAGER "bootefi bootmgr;"
 #else
 #define BOOTENV_SHARED_EFI
 #define SCAN_DEV_FOR_EFI
+#define BOOT_EFI_BOOT_MANAGER
 #endif
 
 #ifdef CONFIG_SATA

include/config_distro_bootcmd.h line 413

Quoted 4 lines
include/config_distro_bootcmd.h +1 -0
@@ -409,6 +410,7 @@
 	BOOT_TARGET_DEVICES(BOOTENV_DEV)                                  \
 	\
 	"distro_bootcmd=" BOOTENV_SET_SCSI_NEED_INIT                      \
+		BOOT_EFI_BOOT_MANAGER					  \

The last-minute change may have introduced a problem. By moving "bootmgr" from scan_dev_for_efi" to here, grub fails to start a grub.cfg menu, saying
"error: no such device: /.disk/info."

Quoted 1 line

Do you have any ideas?

I would guess that bootmgr doesn't set the loaded image target correctly and before it just happened to work because there was a load command before the bootmgr command?

https://github.com/u-boot/u-boot/blob/master/cmd/fs.c#L26

Alex

#4 lore raw

PATCH v2 1/3 efi_loader: rework fdt handling in distro boot script

Quoted 119 lines · Alexander Graf
Quoted 116 lines · AKASHI Takahiro
Quoted 105 lines · AKASHI Takahiro

The current scenario for default UEFI booting, scan_dev_for_efi, has several issues:
* load dtb dynamically even if its loacation (device) is not the same as BOOTEFI_NAME binary's, (reported by Alex)
* invoke 'bootmgr' only if BOOTEFI_NAME binary does exit even though 'bootmgr' can and should work independently whether or not the binary exist,
* in addition, invoke 'bootmgr' with dynamically-loaded dtb.
This behavior is not expected. (reported by Alex)
* always assume that a 'fdtfile' variable is defined,
("test -e ${devtype} ${devnum}:${distro_bootpart} "${prefix}${efi_fdtfile}" always returns true even if fdtfile is NULL with prefix=="/".)
* redundantly check for 'fdt_addr_r' in boot_efi_binary

In this patch, all the issues above are sorted out.
Please note that the default behavior can be customized with:
fdtfile: a dtb file name
efi_dtb_prefixes: a list of paths for searching for a dtb file

(this feature does work even without this patch.)

---
 include/config_distro_bootcmd.h | 38 +++++++++++++++++----------------
 1 file changed, 20 insertions(+), 18 deletions(-)
include/config_distro_bootcmd.h +19 -18
index 373fee78a999..256698309eb9 100644
@@ -115,7 +115,7 @@
  */
 #define BOOTENV_EFI_SET_FDTFILE_FALLBACK                                  \
 	"if test -z \"${fdtfile}\" -a -n \"${soc}\"; then "               \
-	  "setenv efi_fdtfile ${soc}-${board}${boardver}.dtb; "           \
+	  "efi_fdtfile=${soc}-${board}${boardver}.dtb; "           \
 	"fi; "
 #else
 #define BOOTENV_EFI_SET_FDTFILE_FALLBACK
@@ -124,26 +124,20 @@
 
 #define BOOTENV_SHARED_EFI                                                \
 	"boot_efi_binary="                                                \
-		"if fdt addr ${fdt_addr_r}; then "                        \
-			"bootefi bootmgr ${fdt_addr_r};"                  \
-		"else "                                                   \
-			"bootefi bootmgr ${fdtcontroladdr};"              \
-		"fi;"                                                     \
 		"load ${devtype} ${devnum}:${distro_bootpart} "           \
 			"${kernel_addr_r} efi/boot/"BOOTEFI_NAME"; "      \
-		"if fdt addr ${fdt_addr_r}; then "                        \
-			"bootefi ${kernel_addr_r} ${fdt_addr_r};"         \
-		"else "                                                   \
-			"bootefi ${kernel_addr_r} ${fdtcontroladdr};"     \
-		"fi\0"                                                    \
+		"bootefi ${kernel_addr_r} ${efi_fdt_addr};\0"		  \
 	\
 	"load_efi_dtb="                                                   \
-		"load ${devtype} ${devnum}:${distro_bootpart} "           \
-			"${fdt_addr_r} ${prefix}${efi_fdtfile}\0"         \
+		"load ${devtype} ${devnum}:${distro_bootpart} "		  \
+			"${fdt_addr_r} ${prefix}${efi_fdtfile}; "	  \
+		"if fdt addr ${fdt_addr_r}; then "			  \
+			"efi_fdt_addr=${fdt_addr_r}; "			  \
+		"fi;\0"							  \
 	\
 	"efi_dtb_prefixes=/ /dtb/ /dtb/current/\0"                        \
-	"scan_dev_for_efi="                                               \
-		"setenv efi_fdtfile ${fdtfile}; "                         \
+	"set_efi_fdt_addr="						  \
+		"efi_fdtfile=${fdtfile}; "                         \
 		BOOTENV_EFI_SET_FDTFILE_FALLBACK                          \
 		"for prefix in ${efi_dtb_prefixes}; do "                  \
 			"if test -e ${devtype} "                          \
@@ -151,19 +145,26 @@
 					"${prefix}${efi_fdtfile}; then "  \
 				"run load_efi_dtb; "                      \
 			"fi;"                                             \
-		"done;"                                                   \
+		"done;\0"                                                   \
+	\
+	"scan_dev_for_efi="                                               \
 		"if test -e ${devtype} ${devnum}:${distro_bootpart} "     \
 					"efi/boot/"BOOTEFI_NAME"; then "  \
 				"echo Found EFI removable media binary "  \
 					"efi/boot/"BOOTEFI_NAME"; "       \
+				"efi_fdt_addr=${fdtcontroladdr}; "	  \
+				"if test -n \"${fdtfile}\"; then "	  \
+					"run set_efi_fdt_addr; "	  \
+				"fi; "					  \
 				"run boot_efi_binary; "                   \
 				"echo EFI LOAD FAILED: continuing...; "   \
-		"fi; "                                                    \
-		"setenv efi_fdtfile\0"
+		"fi;\0"
 #define SCAN_DEV_FOR_EFI "run scan_dev_for_efi;"
+#define BOOT_EFI_BOOT_MANAGER "bootefi bootmgr;"
 #else
 #define BOOTENV_SHARED_EFI
 #define SCAN_DEV_FOR_EFI
+#define BOOT_EFI_BOOT_MANAGER
 #endif
 
 #ifdef CONFIG_SATA

include/config_distro_bootcmd.h line 413

Quoted 4 lines
include/config_distro_bootcmd.h +1 -0
@@ -409,6 +410,7 @@
 	BOOT_TARGET_DEVICES(BOOTENV_DEV)                                  \
 	\
 	"distro_bootcmd=" BOOTENV_SET_SCSI_NEED_INIT                      \
+		BOOT_EFI_BOOT_MANAGER					  \

The last-minute change may have introduced a problem. By moving "bootmgr" from scan_dev_for_efi" to here, grub fails to start a grub.cfg menu, saying
"error: no such device: /.disk/info."

Quoted 5 lines
Quoted 1 line

Do you have any ideas?

I would guess that bootmgr doesn't set the loaded image target correctly and before it just happened to work because there was a load command before the bootmgr command?

The root cause was that efi_init_obj_list(), particularly efi_disk_register(), is executed only once.
In my case, efi bootmgr is called before "usb start" in scan_dev_for_efi, and any USB devices will not be added to efi object list forever. Therefore, later on, grub itself can start but cannot detect/access its own boot device (USB mass storage) via efi interface.

I think we can fix this problem in several ways:
1. run all 'device-scanning' commands, like "usb start" and "scsi scan," before calling bootmgr in distro_bootcmd,
2. modify efi_obj_init_list() to check and register newly-detected devices,
3. add a device to efi object list dynamically whenever a 'device-scanning' command detects one,
4. search and check for a device on-the-fly with each efi device path (or handle?) specified in efi interface

What do you think?

-Takahiro Akashi

Quoted 4 lines

https://github.com/u-boot/u-boot/blob/master/cmd/fs.c#L26

Alex

#5 lore raw

PATCH v2 1/3 efi_loader: rework fdt handling in distro boot script

Quoted 133 lines · AKASHI Takahiro
Quoted 119 lines · Alexander Graf
Quoted 116 lines · AKASHI Takahiro
Quoted 105 lines · AKASHI Takahiro

The current scenario for default UEFI booting, scan_dev_for_efi, has several issues:
* load dtb dynamically even if its loacation (device) is not the same as BOOTEFI_NAME binary's, (reported by Alex)
* invoke 'bootmgr' only if BOOTEFI_NAME binary does exit even though 'bootmgr' can and should work independently whether or not the binary exist,
* in addition, invoke 'bootmgr' with dynamically-loaded dtb.
This behavior is not expected. (reported by Alex)
* always assume that a 'fdtfile' variable is defined,
("test -e ${devtype} ${devnum}:${distro_bootpart} "${prefix}${efi_fdtfile}" always returns true even if fdtfile is NULL with prefix=="/".)
* redundantly check for 'fdt_addr_r' in boot_efi_binary

In this patch, all the issues above are sorted out.
Please note that the default behavior can be customized with:
fdtfile: a dtb file name
efi_dtb_prefixes: a list of paths for searching for a dtb file

(this feature does work even without this patch.)

---
 include/config_distro_bootcmd.h | 38 +++++++++++++++++----------------
 1 file changed, 20 insertions(+), 18 deletions(-)
include/config_distro_bootcmd.h +19 -18
index 373fee78a999..256698309eb9 100644
@@ -115,7 +115,7 @@
  */
 #define BOOTENV_EFI_SET_FDTFILE_FALLBACK                                  \
 	"if test -z \"${fdtfile}\" -a -n \"${soc}\"; then "               \
-	  "setenv efi_fdtfile ${soc}-${board}${boardver}.dtb; "           \
+	  "efi_fdtfile=${soc}-${board}${boardver}.dtb; "           \
 	"fi; "
 #else
 #define BOOTENV_EFI_SET_FDTFILE_FALLBACK
@@ -124,26 +124,20 @@
 
 #define BOOTENV_SHARED_EFI                                                \
 	"boot_efi_binary="                                                \
-		"if fdt addr ${fdt_addr_r}; then "                        \
-			"bootefi bootmgr ${fdt_addr_r};"                  \
-		"else "                                                   \
-			"bootefi bootmgr ${fdtcontroladdr};"              \
-		"fi;"                                                     \
 		"load ${devtype} ${devnum}:${distro_bootpart} "           \
 			"${kernel_addr_r} efi/boot/"BOOTEFI_NAME"; "      \
-		"if fdt addr ${fdt_addr_r}; then "                        \
-			"bootefi ${kernel_addr_r} ${fdt_addr_r};"         \
-		"else "                                                   \
-			"bootefi ${kernel_addr_r} ${fdtcontroladdr};"     \
-		"fi\0"                                                    \
+		"bootefi ${kernel_addr_r} ${efi_fdt_addr};\0"		  \
 	\
 	"load_efi_dtb="                                                   \
-		"load ${devtype} ${devnum}:${distro_bootpart} "           \
-			"${fdt_addr_r} ${prefix}${efi_fdtfile}\0"         \
+		"load ${devtype} ${devnum}:${distro_bootpart} "		  \
+			"${fdt_addr_r} ${prefix}${efi_fdtfile}; "	  \
+		"if fdt addr ${fdt_addr_r}; then "			  \
+			"efi_fdt_addr=${fdt_addr_r}; "			  \
+		"fi;\0"							  \
 	\
 	"efi_dtb_prefixes=/ /dtb/ /dtb/current/\0"                        \
-	"scan_dev_for_efi="                                               \
-		"setenv efi_fdtfile ${fdtfile}; "                         \
+	"set_efi_fdt_addr="						  \
+		"efi_fdtfile=${fdtfile}; "                         \
 		BOOTENV_EFI_SET_FDTFILE_FALLBACK                          \
 		"for prefix in ${efi_dtb_prefixes}; do "                  \
 			"if test -e ${devtype} "                          \
@@ -151,19 +145,26 @@
 					"${prefix}${efi_fdtfile}; then "  \
 				"run load_efi_dtb; "                      \
 			"fi;"                                             \
-		"done;"                                                   \
+		"done;\0"                                                   \
+	\
+	"scan_dev_for_efi="                                               \
 		"if test -e ${devtype} ${devnum}:${distro_bootpart} "     \
 					"efi/boot/"BOOTEFI_NAME"; then "  \
 				"echo Found EFI removable media binary "  \
 					"efi/boot/"BOOTEFI_NAME"; "       \
+				"efi_fdt_addr=${fdtcontroladdr}; "	  \
+				"if test -n \"${fdtfile}\"; then "	  \
+					"run set_efi_fdt_addr; "	  \
+				"fi; "					  \
 				"run boot_efi_binary; "                   \
 				"echo EFI LOAD FAILED: continuing...; "   \
-		"fi; "                                                    \
-		"setenv efi_fdtfile\0"
+		"fi;\0"
 #define SCAN_DEV_FOR_EFI "run scan_dev_for_efi;"
+#define BOOT_EFI_BOOT_MANAGER "bootefi bootmgr;"
 #else
 #define BOOTENV_SHARED_EFI
 #define SCAN_DEV_FOR_EFI
+#define BOOT_EFI_BOOT_MANAGER
 #endif
 
 #ifdef CONFIG_SATA

include/config_distro_bootcmd.h line 413

Quoted 4 lines
include/config_distro_bootcmd.h +1 -0
@@ -409,6 +410,7 @@
 	BOOT_TARGET_DEVICES(BOOTENV_DEV)                                  \
 	\
 	"distro_bootcmd=" BOOTENV_SET_SCSI_NEED_INIT                      \
+		BOOT_EFI_BOOT_MANAGER					  \

The last-minute change may have introduced a problem. By moving "bootmgr" from scan_dev_for_efi" to here, grub fails to start a grub.cfg menu, saying
"error: no such device: /.disk/info."

Quoted 5 lines
Quoted 1 line

Do you have any ideas?

I would guess that bootmgr doesn't set the loaded image target correctly and before it just happened to work because there was a load command before the bootmgr command?

The root cause was that efi_init_obj_list(), particularly efi_disk_register(), is executed only once.
In my case, efi bootmgr is called before "usb start" in scan_dev_for_efi, and any USB devices will not be added to efi object list forever. Therefore, later on, grub itself can start but cannot detect/access its own boot device (USB mass storage) via efi interface.

Quoted 3 lines

I think we can fix this problem in several ways:
1. run all 'device-scanning' commands, like "usb start" and "scsi scan," before calling bootmgr in distro_bootcmd,

This would work, though it's slightly complicated - hm :/.

Quoted 1 line

2. modify efi_obj_init_list() to check and register newly-detected devices,

That won't work, because then efibootmgr won't be able to boot from USB, no?

Quoted 2 lines

3. add a device to efi object list dynamically whenever a 'device-scanning' command detects one,

Same here I assume.

Quoted 2 lines

4. search and check for a device on-the-fly with each efi device path (or handle?) specified in efi interface

That won't work either, because we simply don't initialize USB in the efibootmgr case, so there won't be anything on the fly ;).

Quoted 2 lines

What do you think?

I guess one of your options above mentions this and I just missed it, but I think we'll have to find out what to initialize in the efibootmgr command based on the device path we're trying to execute and then initialize that respective subsystem.

So if we see that the device path involves USB, we need to run "usb start" from within the efibootmgr code.

Alex

#6 lore raw

PATCH v2 1/3 efi_loader: rework fdt handling in distro boot script

Quoted 160 lines · Alexander Graf
Quoted 133 lines · AKASHI Takahiro
Quoted 119 lines · Alexander Graf
Quoted 116 lines · AKASHI Takahiro
Quoted 105 lines · AKASHI Takahiro

The current scenario for default UEFI booting, scan_dev_for_efi, has several issues:
* load dtb dynamically even if its loacation (device) is not the same as BOOTEFI_NAME binary's, (reported by Alex)
* invoke 'bootmgr' only if BOOTEFI_NAME binary does exit even though 'bootmgr' can and should work independently whether or not the binary exist,
* in addition, invoke 'bootmgr' with dynamically-loaded dtb.
This behavior is not expected. (reported by Alex)
* always assume that a 'fdtfile' variable is defined,
("test -e ${devtype} ${devnum}:${distro_bootpart} "${prefix}${efi_fdtfile}" always returns true even if fdtfile is NULL with prefix=="/".)
* redundantly check for 'fdt_addr_r' in boot_efi_binary

In this patch, all the issues above are sorted out.
Please note that the default behavior can be customized with:
fdtfile: a dtb file name
efi_dtb_prefixes: a list of paths for searching for a dtb file

(this feature does work even without this patch.)

---
 include/config_distro_bootcmd.h | 38 +++++++++++++++++----------------
 1 file changed, 20 insertions(+), 18 deletions(-)
include/config_distro_bootcmd.h +19 -18
index 373fee78a999..256698309eb9 100644
@@ -115,7 +115,7 @@
  */
 #define BOOTENV_EFI_SET_FDTFILE_FALLBACK                                  \
 	"if test -z \"${fdtfile}\" -a -n \"${soc}\"; then "               \
-	  "setenv efi_fdtfile ${soc}-${board}${boardver}.dtb; "           \
+	  "efi_fdtfile=${soc}-${board}${boardver}.dtb; "           \
 	"fi; "
 #else
 #define BOOTENV_EFI_SET_FDTFILE_FALLBACK
@@ -124,26 +124,20 @@
 
 #define BOOTENV_SHARED_EFI                                                \
 	"boot_efi_binary="                                                \
-		"if fdt addr ${fdt_addr_r}; then "                        \
-			"bootefi bootmgr ${fdt_addr_r};"                  \
-		"else "                                                   \
-			"bootefi bootmgr ${fdtcontroladdr};"              \
-		"fi;"                                                     \
 		"load ${devtype} ${devnum}:${distro_bootpart} "           \
 			"${kernel_addr_r} efi/boot/"BOOTEFI_NAME"; "      \
-		"if fdt addr ${fdt_addr_r}; then "                        \
-			"bootefi ${kernel_addr_r} ${fdt_addr_r};"         \
-		"else "                                                   \
-			"bootefi ${kernel_addr_r} ${fdtcontroladdr};"     \
-		"fi\0"                                                    \
+		"bootefi ${kernel_addr_r} ${efi_fdt_addr};\0"		  \
 	\
 	"load_efi_dtb="                                                   \
-		"load ${devtype} ${devnum}:${distro_bootpart} "           \
-			"${fdt_addr_r} ${prefix}${efi_fdtfile}\0"         \
+		"load ${devtype} ${devnum}:${distro_bootpart} "		  \
+			"${fdt_addr_r} ${prefix}${efi_fdtfile}; "	  \
+		"if fdt addr ${fdt_addr_r}; then "			  \
+			"efi_fdt_addr=${fdt_addr_r}; "			  \
+		"fi;\0"							  \
 	\
 	"efi_dtb_prefixes=/ /dtb/ /dtb/current/\0"                        \
-	"scan_dev_for_efi="                                               \
-		"setenv efi_fdtfile ${fdtfile}; "                         \
+	"set_efi_fdt_addr="						  \
+		"efi_fdtfile=${fdtfile}; "                         \
 		BOOTENV_EFI_SET_FDTFILE_FALLBACK                          \
 		"for prefix in ${efi_dtb_prefixes}; do "                  \
 			"if test -e ${devtype} "                          \
@@ -151,19 +145,26 @@
 					"${prefix}${efi_fdtfile}; then "  \
 				"run load_efi_dtb; "                      \
 			"fi;"                                             \
-		"done;"                                                   \
+		"done;\0"                                                   \
+	\
+	"scan_dev_for_efi="                                               \
 		"if test -e ${devtype} ${devnum}:${distro_bootpart} "     \
 					"efi/boot/"BOOTEFI_NAME"; then "  \
 				"echo Found EFI removable media binary "  \
 					"efi/boot/"BOOTEFI_NAME"; "       \
+				"efi_fdt_addr=${fdtcontroladdr}; "	  \
+				"if test -n \"${fdtfile}\"; then "	  \
+					"run set_efi_fdt_addr; "	  \
+				"fi; "					  \
 				"run boot_efi_binary; "                   \
 				"echo EFI LOAD FAILED: continuing...; "   \
-		"fi; "                                                    \
-		"setenv efi_fdtfile\0"
+		"fi;\0"
 #define SCAN_DEV_FOR_EFI "run scan_dev_for_efi;"
+#define BOOT_EFI_BOOT_MANAGER "bootefi bootmgr;"
 #else
 #define BOOTENV_SHARED_EFI
 #define SCAN_DEV_FOR_EFI
+#define BOOT_EFI_BOOT_MANAGER
 #endif
 
 #ifdef CONFIG_SATA

include/config_distro_bootcmd.h line 413

Quoted 4 lines
include/config_distro_bootcmd.h +1 -0
@@ -409,6 +410,7 @@
 	BOOT_TARGET_DEVICES(BOOTENV_DEV)                                  \
 	\
 	"distro_bootcmd=" BOOTENV_SET_SCSI_NEED_INIT                      \
+		BOOT_EFI_BOOT_MANAGER					  \

The last-minute change may have introduced a problem. By moving "bootmgr" from scan_dev_for_efi" to here, grub fails to start a grub.cfg menu, saying
"error: no such device: /.disk/info."

Quoted 5 lines
Quoted 1 line

Do you have any ideas?

I would guess that bootmgr doesn't set the loaded image target correctly and before it just happened to work because there was a load command before the bootmgr command?

The root cause was that efi_init_obj_list(), particularly efi_disk_register(), is executed only once.
In my case, efi bootmgr is called before "usb start" in scan_dev_for_efi, and any USB devices will not be added to efi object list forever. Therefore, later on, grub itself can start but cannot detect/access its own boot device (USB mass storage) via efi interface.

Quoted 3 lines

I think we can fix this problem in several ways:
1. run all 'device-scanning' commands, like "usb start" and "scsi scan," before calling bootmgr in distro_bootcmd,

This would work, though it's slightly complicated - hm :/.

Quoted 1 line

2. modify efi_obj_init_list() to check and register newly-detected devices,

That won't work, because then efibootmgr won't be able to boot from USB, no?

Quoted 2 lines

3. add a device to efi object list dynamically whenever a 'device-scanning' command detects one,

Same here I assume.

Quoted 2 lines

4. search and check for a device on-the-fly with each efi device path (or handle?) specified in efi interface

That won't work either, because we simply don't initialize USB in the efibootmgr case, so there won't be anything on the fly ;).

Quoted 2 lines

What do you think?

Quoted 7 lines

I guess one of your options above mentions this and I just missed it, but I think we'll have to find out what to initialize in the efibootmgr command based on the device path we're trying to execute and then initialize that respective subsystem.

So if we see that the device path involves USB, we need to run "usb start" from within the efibootmgr code.

I don't think that this behavior is consistent with other U-boot commands. For example, "load usb 0:1 ..." doesn't work unless we run "usb start" first. Efi bootmgr should not be an exception.

-Takahiro Akashi

Quoted 2 lines

Alex

#7 lore raw

PATCH v2 2/3 ARM: qemu-arm: rework Kconfig

In reply to AKASHI Takahiro

Define a missing CONFIG_SYS_SOC and move some CONFIG_SYS_* to a more canonical place (i.e. under board).

---
 arch/arm/mach-qemu/Kconfig       | 18 ++++++++++--------
 board/emulation/qemu-arm/Kconfig |  6 ++++++
 2 files changed, 16 insertions(+), 8 deletions(-)
arch/arm/mach-qemu/Kconfig +10 -8
index a2e4b98b8887..d75a95183a75 100644
@@ -3,22 +3,24 @@ if ARCH_QEMU
 config SYS_VENDOR
 	default "emulation"
 
-config SYS_BOARD
-	default "qemu-arm"
+config SYS_SOC
+	default "qemu"
 
-config SYS_CONFIG_NAME
-	default "qemu-arm"
-
-endif
+choice
+	prompt "QEMU cpu type"
 
 config TARGET_QEMU_ARM_32BIT
-	bool "Support qemu_arm"
+	bool "Arm"
 	depends on ARCH_QEMU
 	select ARCH_SUPPORT_PSCI
 	select CPU_V7A
 	select SYS_ARCH_TIMER
 
 config TARGET_QEMU_ARM_64BIT
-	bool "Support qemu_arm64"
+	bool "AArch64"
 	depends on ARCH_QEMU
 	select ARM64
+
+endchoice
+
+endif
board/emulation/qemu-arm/Kconfig +6 -0
index d1c08c2f6a80..ef49e4e85f04 100644
@@ -1,5 +1,11 @@
 if TARGET_QEMU_ARM_32BIT || TARGET_QEMU_ARM_64BIT
 
+config SYS_BOARD
+	default "qemu-arm"
+
+config SYS_CONFIG_NAME
+	default "qemu-arm"
+
 config SYS_TEXT_BASE
 	default 0x00000000
 
Signature · 1 line
2.19.0
#8 lore raw

PATCH v2 3/3 ARM: qemu-arm: define fdt_addr_r

In reply to AKASHI Takahiro

This variable, fdt_addr_t, is missing in the current qemu-arm.h while it seems to be mandatory, at least, to run distro_bootcmd as expected. So just add its definition. A size of 1MB would be enough.

---
 include/configs/qemu-arm.h | 1 +
 1 file changed, 1 insertion(+)
include/configs/qemu-arm.h +1 -0
index 91fb8d47edf8..0e66f946dde5 100644
@@ -55,6 +55,7 @@
 	"fdt_high=0xffffffff\0" \
 	"initrd_high=0xffffffff\0" \
 	"fdt_addr=0x40000000\0" \
+	"fdt_addr_r=0x40100000\0" \
 	"scriptaddr=0x40200000\0" \
 	"pxefile_addr_r=0x40300000\0" \
 	"kernel_addr_r=0x40400000\0" \
Signature · 1 line
2.19.0
#9 lore raw

PATCH v2 3/3 ARM: qemu-arm: define fdt_addr_r

Hi Takahiro,

Quoted 14 lines · On Mon, 22 Oct 2018 13:40:07 +0900 AKASHI Takahiro…

This variable, fdt_addr_t, is missing in the current qemu-arm.h while it seems to be mandatory, at least, to run distro_bootcmd as expected. So just add its definition. A size of 1MB would be enough.

---
 include/configs/qemu-arm.h | 1 +
 1 file changed, 1 insertion(+)
include/configs/qemu-arm.h +0 -0
index 91fb8d47edf8..0e66f946dde5 100644

include/configs/qemu-arm.h line 61

Quoted 7 lines
include/configs/qemu-arm.h +1 -0
@@ -55,6 +55,7 @@
 	"fdt_high=0xffffffff\0" \
 	"initrd_high=0xffffffff\0" \
 	"fdt_addr=0x40000000\0" \
+	"fdt_addr_r=0x40100000\0" \
 	"scriptaddr=0x40200000\0" \
 	"pxefile_addr_r=0x40300000\0" \
 	"kernel_addr_r=0x40400000\0" \

The same problem as in the previous version still exists; applying these as-is would regress any boot entries in PXE files that use the FDTDIR directive since it'd try to load a non-existent .dtb and fail.

We need some way to avoid that; maybe some magic value (e.g. fdtfile=none) or a separate environment variable or CONFIG_ option.

- Tuomas