Commit 20898ea9340a4fd1631a4057b8de011b9f166255

Authored by Alexander Graf
Committed by Tom Rini
1 parent 210be5c4cb

distro: Add efi pxe boot code

Now that we can expose network functionality to EFI applications,
the logical next step is to load them via pxe to execute them as
well.

This patch adds the necessary bits to the distro script to automatically
load and execute EFI payloads. It identifies the dhcp client as a uEFI
capable PXE client, hoping the server returns a tftp path to a workable
EFI binary that we can then execute.

To enable boards that don't come with a working device tree preloaded,
this patch also adds support to load a device tree from the /dtb directory
on the remote tftp server.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Tom Rini <trini@konsulko.com>

Showing 2 changed files with 57 additions and 3 deletions Side-by-side Diff

include/config_distro_bootcmd.h
... ... @@ -230,13 +230,58 @@
230 230 #endif
231 231  
232 232 #if defined(CONFIG_CMD_DHCP)
  233 +#if defined(CONFIG_EFI_LOADER)
  234 +#if defined(CONFIG_ARM64)
  235 +#define BOOTENV_EFI_PXE_ARCH "0xb"
  236 +#define BOOTENV_EFI_PXE_VCI "PXEClient:Arch:00011:UNDI:003000"
  237 +#elif defined(CONFIG_ARM)
  238 +#define BOOTENV_EFI_PXE_ARCH "0xa"
  239 +#define BOOTENV_EFI_PXE_VCI "PXEClient:Arch:00010:UNDI:003000"
  240 +#elif defined(CONFIG_X86)
  241 +/* Always assume we're running 64bit */
  242 +#define BOOTENV_EFI_PXE_ARCH "0x7"
  243 +#define BOOTENV_EFI_PXE_VCI "PXEClient:Arch:00007:UNDI:003000"
  244 +#else
  245 +#error Please specify an EFI client identifier
  246 +#endif
  247 +
  248 +/*
  249 + * Ask the dhcp server for an EFI binary. If we get one, check for a
  250 + * device tree in the same folder. Then boot everything. If the file was
  251 + * not an EFI binary, we just return from the bootefi command and continue.
  252 + */
  253 +#define BOOTENV_EFI_RUN_DHCP \
  254 + "setenv efi_fdtfile ${fdtfile}; " \
  255 + BOOTENV_EFI_SET_FDTFILE_FALLBACK \
  256 + "setenv efi_old_vci ${bootp_vci};" \
  257 + "setenv efi_old_arch ${bootp_arch};" \
  258 + "setenv bootp_vci " BOOTENV_EFI_PXE_VCI ";" \
  259 + "setenv bootp_arch " BOOTENV_EFI_PXE_ARCH ";" \
  260 + "if dhcp ${kernel_addr_r}; then " \
  261 + "tftpboot ${fdt_addr_r} dtb/${efi_fdtfile};" \
  262 + "if fdt addr ${fdt_addr_r}; then " \
  263 + "bootefi ${kernel_addr_r} ${fdt_addr_r}; " \
  264 + "else " \
  265 + "bootefi ${kernel_addr_r} ${fdtcontroladdr};" \
  266 + "fi;" \
  267 + "fi;" \
  268 + "setenv bootp_vci ${efi_old_vci};" \
  269 + "setenv bootp_arch ${efi_old_arch};" \
  270 + "setenv efi_fdtfile;" \
  271 + "setenv efi_old_arch;" \
  272 + "setenv efi_old_vci;"
  273 +#else
  274 +#define BOOTENV_EFI_RUN_DHCP
  275 +#endif
233 276 #define BOOTENV_DEV_DHCP(devtypeu, devtypel, instance) \
234 277 "bootcmd_dhcp=" \
235 278 BOOTENV_RUN_NET_USB_START \
236 279 BOOTENV_RUN_NET_PCI_ENUM \
237 280 "if dhcp ${scriptaddr} ${boot_script_dhcp}; then " \
238 281 "source ${scriptaddr}; " \
239   - "fi\0"
  282 + "fi;" \
  283 + BOOTENV_EFI_RUN_DHCP \
  284 + "\0"
240 285 #define BOOTENV_DEV_NAME_DHCP(devtypeu, devtypel, instance) \
241 286 "dhcp "
242 287 #else
... ... @@ -413,11 +413,20 @@
413 413  
414 414 static u8 *add_vci(u8 *e)
415 415 {
  416 + char *vci = NULL;
  417 + char *env_vci = getenv("bootp_vci");
  418 +
416 419 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_NET_VCI_STRING)
417   - put_vci(e, CONFIG_SPL_NET_VCI_STRING);
  420 + vci = CONFIG_SPL_NET_VCI_STRING;
418 421 #elif defined(CONFIG_BOOTP_VCI_STRING)
419   - put_vci(e, CONFIG_BOOTP_VCI_STRING);
  422 + vci = CONFIG_BOOTP_VCI_STRING;
420 423 #endif
  424 +
  425 + if (env_vci)
  426 + vci = env_vci;
  427 +
  428 + if (vci)
  429 + put_vci(e, vci);
421 430  
422 431 return e;
423 432 }