[PATCH v1 0/3] bootflow: bootmeth_efi: Fix network efi boot

Currently bootmeth_efi crashes while doing a network (dhcp) boot. This patch series fixes issues and both network and disk boot works.
Shantur Rathore (3): bootflow: bootmeth_efi: Set bootp_arch as hex bootflow: bootmeth_efi: Don't set bootdev again bootflow: bootmeth_efi: Handle fdt not available.
boot/bootmeth_efi.c | 15 ++++++++++----- include/bootflow.h | 1 + 2 files changed, 11 insertions(+), 5 deletions(-)

bootmeth_efi sets up bootp_arch which is read later in bootp.c Currently bootp_arch is being set as integer string and being read in bootp.c as hex, this sends incorrect arch value to dhcp server which in return sends wrong file for network boot.
For ARM64 UEFI Arch value is 0xb (11), here we set environment as 11 and later is read as 0x11 and 17 is sent to dhcp server.
Setting it as hex string fixes the problem.
Signed-off-by: Shantur Rathore i@shantur.com --- boot/bootmeth_efi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c index ae936c8daa..ad3f4330da 100644 --- a/boot/bootmeth_efi.c +++ b/boot/bootmeth_efi.c @@ -338,7 +338,7 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow) ret = env_set("bootp_vci", str); if (ret) return log_msg_ret("vcs", ret); - ret = env_set_ulong("bootp_arch", arch); + ret = env_set_hex("bootp_arch", arch); if (ret) return log_msg_ret("ars", ret);

efi_set_bootdev is already called as part of tftp while doing dhcp_run() Doing this again crashes U-boot and we don't need to call again.
Signed-off-by: Shantur Rathore i@shantur.com --- boot/bootmeth_efi.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c index ad3f4330da..a65d8ff582 100644 --- a/boot/bootmeth_efi.c +++ b/boot/bootmeth_efi.c @@ -359,9 +359,6 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow) return log_msg_ret("sz", -EINVAL); bflow->size = size;
- /* do the hideous EFI hack */ - efi_set_bootdev("Net", "", bflow->fname, map_sysmem(addr, 0), - bflow->size);
/* read the DT file also */ fdt_addr_str = env_get("fdt_addr_r");

While booting with efi, if fdt isn't available externally, just use the built-in one.
Signed-off-by: Shantur Rathore i@shantur.com --- boot/bootmeth_efi.c | 10 +++++++++- include/bootflow.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c index a65d8ff582..c1e15b83a3 100644 --- a/boot/bootmeth_efi.c +++ b/boot/bootmeth_efi.c @@ -312,6 +312,7 @@ static int distro_efi_try_bootflow_files(struct udevice *dev, */ } else { log_debug("No device tree available\n"); + bflow->flags |= BOOTFLOWF_USE_BUILTIN_FDT; }
return 0; @@ -381,6 +382,7 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow) bflow->fdt_addr = fdt_addr; } else { log_debug("No device tree available\n"); + bflow->flags |= BOOTFLOWF_USE_BUILTIN_FDT; }
bflow->state = BOOTFLOWST_READY; @@ -442,7 +444,13 @@ static int distro_efi_boot(struct udevice *dev, struct bootflow *bflow) * At some point we can add a real interface to bootefi so we can call * this directly. For now, go through the CLI, like distro boot. */ - snprintf(cmd, sizeof(cmd), "bootefi %lx %lx", kernel, fdt); + if (bflow->flags & BOOTFLOWF_USE_BUILTIN_FDT) { + log_debug("Booting with built-in fdt\n"); + snprintf(cmd, sizeof(cmd), "bootefi %lx", kernel); + } else { + snprintf(cmd, sizeof(cmd), "bootefi %lx %lx", kernel, fdt); + } + if (run_command(cmd, 0)) return log_msg_ret("run", -EINVAL);
diff --git a/include/bootflow.h b/include/bootflow.h index 44d3741eac..ea6c6ffc0c 100644 --- a/include/bootflow.h +++ b/include/bootflow.h @@ -46,6 +46,7 @@ enum bootflow_state_t { */ enum bootflow_flags_t { BOOTFLOWF_USE_PRIOR_FDT = 1 << 0, + BOOTFLOWF_USE_BUILTIN_FDT = 1 << 1, };
/**
participants (1)
-
Shantur Rathore