diff mbox series

[v5,06/17] efi_loader: bootmgr: add booting from removable media

Message ID 20220428080950.23509-7-masahisa.kojima@linaro.org
State New
Headers show
Series enable menu-driven boot device selection | expand

Commit Message

Masahisa Kojima April 28, 2022, 8:09 a.m. UTC
From: AKASHI Takahiro <takahiro.akashi@linaro.org>

Under the current implementation, booting from removable media using
a architecture-specific default image name, say BOOTAA64.EFI, is
supported only in distro_bootcmd script. See the commit 74522c898b35
("efi_loader: Add distro boot script for removable media").

This is, however, half-baked implementation because
1) UEFI specification requires this feature to be implemented as part
   of Boot Manager's responsibility:

  3 - Boot Manager
  3.5.1 Boot via the Simple File Protocol
  When booting via the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, the FilePath will
  start with a device path that points to the device that implements the
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL or the EFI_BLOCK_IO_PROTOCOL. The next
  part of the FilePath may point to the file name, including
  subdirectories, which contain the bootable image. If the file name is
  a null device path, the file name must be generated from the rules
  defined below.
  ...
  3.5.1.1 Removable Media Boot Behavior
  To generate a file name when none is present in the FilePath, the
  firmware must append a default file name in the form
  \EFI\BOOT\BOOT{machine type short-name}.EFI ...

2) So (1) entails the hehavior that the user's preference of boot media
   order should be determined by Boot#### and BootOrder variables.

With this patch, the semantics mentioned above is fully implemented.
For example, if you want to boot the system from USB and SCSI in this
order,
* define Boot0001 which contains only a device path to the USB device
  (without any file path/name)
* define Boot0002 which contains only a device path to the SCSI device,
and
* set BootOrder to Boot0001:Boot0002

To avoid build error for sandbox, default file name "BOOTSANDBOX.efi"
is defined even if it is out of scope of UEFI specification.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
---
Changes in v5:
- add default file name definition for SANDBOX to avoid build error

Changes from original version:
- create new include file "efi_default_filename.h" to
  avoid conflict with config_distro_bootcmd.h
- modify the target pointer of efi_free_pool(), expand_media_path() should
  only free the pointer allocated by efi_dp_from_file() function.
 include/config_distro_bootcmd.h | 14 +--------
 include/efi_default_filename.h  | 33 ++++++++++++++++++++++
 lib/efi_loader/efi_bootmgr.c    | 50 ++++++++++++++++++++++++++++++++-
 3 files changed, 83 insertions(+), 14 deletions(-)
 create mode 100644 include/efi_default_filename.h

Comments

Heinrich Schuchardt April 29, 2022, 5:03 p.m. UTC | #1
On 4/28/22 10:09, Masahisa Kojima wrote:
> From: AKASHI Takahiro <takahiro.akashi@linaro.org>
>
> Under the current implementation, booting from removable media using
> a architecture-specific default image name, say BOOTAA64.EFI, is
> supported only in distro_bootcmd script. See the commit 74522c898b35
> ("efi_loader: Add distro boot script for removable media").
>
> This is, however, half-baked implementation because
> 1) UEFI specification requires this feature to be implemented as part
>     of Boot Manager's responsibility:
>
>    3 - Boot Manager
>    3.5.1 Boot via the Simple File Protocol
>    When booting via the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, the FilePath will
>    start with a device path that points to the device that implements the
>    EFI_SIMPLE_FILE_SYSTEM_PROTOCOL or the EFI_BLOCK_IO_PROTOCOL. The next
>    part of the FilePath may point to the file name, including
>    subdirectories, which contain the bootable image. If the file name is
>    a null device path, the file name must be generated from the rules
>    defined below.
>    ...
>    3.5.1.1 Removable Media Boot Behavior
>    To generate a file name when none is present in the FilePath, the
>    firmware must append a default file name in the form
>    \EFI\BOOT\BOOT{machine type short-name}.EFI ...
>
> 2) So (1) entails the hehavior that the user's preference of boot media
>     order should be determined by Boot#### and BootOrder variables.
>
> With this patch, the semantics mentioned above is fully implemented.
> For example, if you want to boot the system from USB and SCSI in this
> order,
> * define Boot0001 which contains only a device path to the USB device
>    (without any file path/name)
> * define Boot0002 which contains only a device path to the SCSI device,
> and
> * set BootOrder to Boot0001:Boot0002
>
> To avoid build error for sandbox, default file name "BOOTSANDBOX.efi"
> is defined even if it is out of scope of UEFI specification.
>
> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
> ---
> Changes in v5:
> - add default file name definition for SANDBOX to avoid build error
>
> Changes from original version:
> - create new include file "efi_default_filename.h" to
>    avoid conflict with config_distro_bootcmd.h
> - modify the target pointer of efi_free_pool(), expand_media_path() should
>    only free the pointer allocated by efi_dp_from_file() function.
>   include/config_distro_bootcmd.h | 14 +--------
>   include/efi_default_filename.h  | 33 ++++++++++++++++++++++
>   lib/efi_loader/efi_bootmgr.c    | 50 ++++++++++++++++++++++++++++++++-
>   3 files changed, 83 insertions(+), 14 deletions(-)
>   create mode 100644 include/efi_default_filename.h
>
> diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
> index c55023889c..6a3110f27b 100644
> --- a/include/config_distro_bootcmd.h
> +++ b/include/config_distro_bootcmd.h
> @@ -91,19 +91,7 @@
>   #endif
>
>   #ifdef CONFIG_EFI_LOADER
> -#if defined(CONFIG_ARM64)
> -#define BOOTEFI_NAME "bootaa64.efi"
> -#elif defined(CONFIG_ARM)
> -#define BOOTEFI_NAME "bootarm.efi"
> -#elif defined(CONFIG_X86_RUN_32BIT)
> -#define BOOTEFI_NAME "bootia32.efi"
> -#elif defined(CONFIG_X86_RUN_64BIT)
> -#define BOOTEFI_NAME "bootx64.efi"
> -#elif defined(CONFIG_ARCH_RV32I)
> -#define BOOTEFI_NAME "bootriscv32.efi"
> -#elif defined(CONFIG_ARCH_RV64I)
> -#define BOOTEFI_NAME "bootriscv64.efi"
> -#endif
> +#include <efi_default_filename.h>
>   #endif
>
>   #ifdef BOOTEFI_NAME
> diff --git a/include/efi_default_filename.h b/include/efi_default_filename.h
> new file mode 100644
> index 0000000000..cb2ef9e131
> --- /dev/null
> +++ b/include/efi_default_filename.h
> @@ -0,0 +1,33 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Default boot file name when none is present in the FilePath.
> + * This is defined in the UEFI specification.
> + *
> + * Copyright (c) 2022, Linaro Limited
> + */
> +#ifndef _EFI_DEFAULT_FILENAME_H
> +#define _EFI_DEFAULT_FILENAME_H
> +
> +#if defined(CONFIG_ARM64)
> +#define BOOTEFI_NAME "BOOTAA64.EFI"
> +#elif defined(CONFIG_ARM)
> +#define BOOTEFI_NAME "BOOTARM.EFI"
> +#elif defined(CONFIG_X86_64)
> +#define BOOTEFI_NAME "BOOTX64.EFI"
> +#elif defined(CONFIG_X86)
> +#define BOOTEFI_NAME "BOOTIA32.EFI"
> +#elif defined(CONFIG_ARCH_RV32I)
> +#define BOOTEFI_NAME "BOOTRISCV32.EFI"
> +#elif defined(CONFIG_ARCH_RV64I)
> +#define BOOTEFI_NAME "BOOTRISCV64.EFI"
> +#elif defined(CONFIG_SANDBOX)
> +/*
> + * SANDBOX is not defined in UEFI specification, but
> + * this definition avoids build failure for SANDBOX.
> + */
> +#define BOOTEFI_NAME "BOOTSANDBOX.EFI"

The sandbox should boot the default binary for the host architecture:

#ifndef _EFI_DEFAULT_FILENAME_H
#define _EFI_DEFAULT_FILENAME_H

#include <host_arch.h>

#undef BOOTEFI_NAME

#if HOST_ARCH == HOST_ARCH_X86_64
#define BOOTEFI_NAME "BOOTX64.EFI"
#endif

#if HOST_ARCH == HOST_ARCH_X86
#define BOOTEFI_NAME "BOOTIA32.EFI"
#endif

#if HOST_ARCH == HOST_ARCH_AARCH64
#define BOOTEFI_NAME "BOOTAA64.EFI"
#endif

#if HOST_ARCH == HOST_ARCH_ARM
#define BOOTEFI_NAME "BOOTARM.EFI"
#endif

#if HOST_ARCH == HOST_ARCH_RISCV32
#define BOOTEFI_NAME "BOOTRISCV32.EFI"
#endif

#if HOST_ARCH == HOST_ARCH_RISCV64
#define BOOTEFI_NAME "BOOTRISCV64.EFI"
#endif

#ifndef BOOTEFI_NAME
#error Unsupported UEFI architecture
#endif

#endif

> +#else
> +#error Unsupported UEFI architecture
> +#endif
> +
> +#endif
> diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
> index 8c04ecbdc8..22a4302aac 100644
> --- a/lib/efi_loader/efi_bootmgr.c
> +++ b/lib/efi_loader/efi_bootmgr.c
> @@ -11,6 +11,7 @@
>   #include <charset.h>
>   #include <log.h>
>   #include <malloc.h>
> +#include <efi_default_filename.h>
>   #include <efi_loader.h>
>   #include <efi_variable.h>
>   #include <asm/unaligned.h>
> @@ -30,6 +31,50 @@ static const struct efi_runtime_services *rs;
>    * should do normal or recovery boot.
>    */
>
> +/**
> + * expand_media_path() - expand a device path for default file name
> + * @device_path:	device path to check against
> + *
> + * If @device_path is a media or disk partition which houses a file
> + * system, this function returns a full device path which contains
> + * an architecture-specific default file name for removable media.
> + *
> + * Return:	a newly allocated device path
> + */
> +static
> +struct efi_device_path *expand_media_path(struct efi_device_path *device_path)
> +{
> +	struct efi_device_path *dp, *full_path;
> +	efi_handle_t handle;
> +	efi_status_t ret;
> +
> +	if (!device_path)
> +		return NULL;
> +
> +	/*
> +	 * If device_path is a (removable) media or partition which provides
> +	 * simple file system protocol, append a default file name to support
> +	 * booting from removable media.
> +	 */
> +	dp = device_path;
> +	ret = efi_locate_device_path(&efi_simple_file_system_protocol_guid,
> +				     &dp, &handle);

Functions defined as EFIAPI must be called with EFI_CALL() due to the
usage of a register for the global data pointer on ARM.

Best regards

Heinrich

> +	if (ret == EFI_SUCCESS) {
> +		if (dp->type == DEVICE_PATH_TYPE_END) {
> +			dp = efi_dp_from_file(NULL, 0,
> +					      "/EFI/BOOT/" BOOTEFI_NAME);
> +			full_path = efi_dp_append(device_path, dp);
> +			efi_free_pool(dp);
> +		} else {
> +			full_path = efi_dp_dup(device_path);
> +		}
> +	} else {
> +		full_path = efi_dp_dup(device_path);
> +	}
> +
> +	return full_path;
> +}
> +
>   /**
>    * try_load_entry() - try to load image for boot option
>    *
> @@ -68,13 +113,16 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle,
>   	}
>
>   	if (lo.attributes & LOAD_OPTION_ACTIVE) {
> +		struct efi_device_path *file_path;
>   		u32 attributes;
>
>   		log_debug("%s: trying to load \"%ls\" from %pD\n",
>   			  __func__, lo.label, lo.file_path);
>
> -		ret = EFI_CALL(efi_load_image(true, efi_root, lo.file_path,
> +		file_path = expand_media_path(lo.file_path);
> +		ret = EFI_CALL(efi_load_image(true, efi_root, file_path,
>   					      NULL, 0, handle));
> +		efi_free_pool(file_path);
>   		if (ret != EFI_SUCCESS) {
>   			log_warning("Loading %ls '%ls' failed\n",
>   				    varname, lo.label);
Mark Kettenis May 5, 2022, 12:05 p.m. UTC | #2
> Date: Fri, 29 Apr 2022 19:03:22 +0200
> From: Heinrich Schuchardt <xypron.glpk@gmx.de>
> 
> On 4/28/22 10:09, Masahisa Kojima wrote:
> > From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> >
> > Under the current implementation, booting from removable media using
> > a architecture-specific default image name, say BOOTAA64.EFI, is
> > supported only in distro_bootcmd script. See the commit 74522c898b35
> > ("efi_loader: Add distro boot script for removable media").
> >
> > This is, however, half-baked implementation because
> > 1) UEFI specification requires this feature to be implemented as part
> >     of Boot Manager's responsibility:
> >
> >    3 - Boot Manager
> >    3.5.1 Boot via the Simple File Protocol
> >    When booting via the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, the FilePath will
> >    start with a device path that points to the device that implements the
> >    EFI_SIMPLE_FILE_SYSTEM_PROTOCOL or the EFI_BLOCK_IO_PROTOCOL. The next
> >    part of the FilePath may point to the file name, including
> >    subdirectories, which contain the bootable image. If the file name is
> >    a null device path, the file name must be generated from the rules
> >    defined below.
> >    ...
> >    3.5.1.1 Removable Media Boot Behavior
> >    To generate a file name when none is present in the FilePath, the
> >    firmware must append a default file name in the form
> >    \EFI\BOOT\BOOT{machine type short-name}.EFI ...
> >
> > 2) So (1) entails the hehavior that the user's preference of boot media
> >     order should be determined by Boot#### and BootOrder variables.
> >
> > With this patch, the semantics mentioned above is fully implemented.
> > For example, if you want to boot the system from USB and SCSI in this
> > order,
> > * define Boot0001 which contains only a device path to the USB device
> >    (without any file path/name)
> > * define Boot0002 which contains only a device path to the SCSI device,
> > and
> > * set BootOrder to Boot0001:Boot0002
> >
> > To avoid build error for sandbox, default file name "BOOTSANDBOX.efi"
> > is defined even if it is out of scope of UEFI specification.
> >
> > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
> > ---
> > Changes in v5:
> > - add default file name definition for SANDBOX to avoid build error
> >
> > Changes from original version:
> > - create new include file "efi_default_filename.h" to
> >    avoid conflict with config_distro_bootcmd.h
> > - modify the target pointer of efi_free_pool(), expand_media_path() should
> >    only free the pointer allocated by efi_dp_from_file() function.
> >   include/config_distro_bootcmd.h | 14 +--------
> >   include/efi_default_filename.h  | 33 ++++++++++++++++++++++
> >   lib/efi_loader/efi_bootmgr.c    | 50 ++++++++++++++++++++++++++++++++-
> >   3 files changed, 83 insertions(+), 14 deletions(-)
> >   create mode 100644 include/efi_default_filename.h
> >
> > diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
> > index c55023889c..6a3110f27b 100644
> > --- a/include/config_distro_bootcmd.h
> > +++ b/include/config_distro_bootcmd.h
> > @@ -91,19 +91,7 @@
> >   #endif
> >
> >   #ifdef CONFIG_EFI_LOADER
> > -#if defined(CONFIG_ARM64)
> > -#define BOOTEFI_NAME "bootaa64.efi"
> > -#elif defined(CONFIG_ARM)
> > -#define BOOTEFI_NAME "bootarm.efi"
> > -#elif defined(CONFIG_X86_RUN_32BIT)
> > -#define BOOTEFI_NAME "bootia32.efi"
> > -#elif defined(CONFIG_X86_RUN_64BIT)
> > -#define BOOTEFI_NAME "bootx64.efi"
> > -#elif defined(CONFIG_ARCH_RV32I)
> > -#define BOOTEFI_NAME "bootriscv32.efi"
> > -#elif defined(CONFIG_ARCH_RV64I)
> > -#define BOOTEFI_NAME "bootriscv64.efi"
> > -#endif
> > +#include <efi_default_filename.h>
> >   #endif
> >
> >   #ifdef BOOTEFI_NAME
> > diff --git a/include/efi_default_filename.h b/include/efi_default_filename.h
> > new file mode 100644
> > index 0000000000..cb2ef9e131
> > --- /dev/null
> > +++ b/include/efi_default_filename.h
> > @@ -0,0 +1,33 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +/*
> > + * Default boot file name when none is present in the FilePath.
> > + * This is defined in the UEFI specification.
> > + *
> > + * Copyright (c) 2022, Linaro Limited
> > + */
> > +#ifndef _EFI_DEFAULT_FILENAME_H
> > +#define _EFI_DEFAULT_FILENAME_H
> > +
> > +#if defined(CONFIG_ARM64)
> > +#define BOOTEFI_NAME "BOOTAA64.EFI"
> > +#elif defined(CONFIG_ARM)
> > +#define BOOTEFI_NAME "BOOTARM.EFI"
> > +#elif defined(CONFIG_X86_64)
> > +#define BOOTEFI_NAME "BOOTX64.EFI"
> > +#elif defined(CONFIG_X86)
> > +#define BOOTEFI_NAME "BOOTIA32.EFI"
> > +#elif defined(CONFIG_ARCH_RV32I)
> > +#define BOOTEFI_NAME "BOOTRISCV32.EFI"
> > +#elif defined(CONFIG_ARCH_RV64I)
> > +#define BOOTEFI_NAME "BOOTRISCV64.EFI"
> > +#elif defined(CONFIG_SANDBOX)
> > +/*
> > + * SANDBOX is not defined in UEFI specification, but
> > + * this definition avoids build failure for SANDBOX.
> > + */
> > +#define BOOTEFI_NAME "BOOTSANDBOX.EFI"
> 
> The sandbox should boot the default binary for the host architecture:
> 
> #ifndef _EFI_DEFAULT_FILENAME_H
> #define _EFI_DEFAULT_FILENAME_H
> 
> #include <host_arch.h>
> 
> #undef BOOTEFI_NAME
> 
> #if HOST_ARCH == HOST_ARCH_X86_64
> #define BOOTEFI_NAME "BOOTX64.EFI"
> #endif
> 
> #if HOST_ARCH == HOST_ARCH_X86
> #define BOOTEFI_NAME "BOOTIA32.EFI"
> #endif
> 
> #if HOST_ARCH == HOST_ARCH_AARCH64
> #define BOOTEFI_NAME "BOOTAA64.EFI"
> #endif
> 
> #if HOST_ARCH == HOST_ARCH_ARM
> #define BOOTEFI_NAME "BOOTARM.EFI"
> #endif
> 
> #if HOST_ARCH == HOST_ARCH_RISCV32
> #define BOOTEFI_NAME "BOOTRISCV32.EFI"
> #endif
> 
> #if HOST_ARCH == HOST_ARCH_RISCV64
> #define BOOTEFI_NAME "BOOTRISCV64.EFI"
> #endif
> 
> #ifndef BOOTEFI_NAME
> #error Unsupported UEFI architecture
> #endif
> 
> #endif

Maybe sanbox is special, but using the host architecture for actual
boards makes no sense.  I see this has made its way into master
already, but when I cross-build for apple_m1_defconfig on an amd64
machine I end up with:

    $ strings ./lib/efi_loader/efi_bootmgr.o | grep BOOT
    /EFI/BOOT/BOOTX64.EFI

The original diff that used CONFIG_ARM64, CONFIG_ARM, etc, did this
right.
Heinrich Schuchardt May 5, 2022, 12:20 p.m. UTC | #3
On 5/5/22 14:05, Mark Kettenis wrote:
>> Date: Fri, 29 Apr 2022 19:03:22 +0200
>> From: Heinrich Schuchardt <xypron.glpk@gmx.de>
>>
>> On 4/28/22 10:09, Masahisa Kojima wrote:
>>> From: AKASHI Takahiro <takahiro.akashi@linaro.org>
>>>
>>> Under the current implementation, booting from removable media using
>>> a architecture-specific default image name, say BOOTAA64.EFI, is
>>> supported only in distro_bootcmd script. See the commit 74522c898b35
>>> ("efi_loader: Add distro boot script for removable media").
>>>
>>> This is, however, half-baked implementation because
>>> 1) UEFI specification requires this feature to be implemented as part
>>>      of Boot Manager's responsibility:
>>>
>>>     3 - Boot Manager
>>>     3.5.1 Boot via the Simple File Protocol
>>>     When booting via the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, the FilePath will
>>>     start with a device path that points to the device that implements the
>>>     EFI_SIMPLE_FILE_SYSTEM_PROTOCOL or the EFI_BLOCK_IO_PROTOCOL. The next
>>>     part of the FilePath may point to the file name, including
>>>     subdirectories, which contain the bootable image. If the file name is
>>>     a null device path, the file name must be generated from the rules
>>>     defined below.
>>>     ...
>>>     3.5.1.1 Removable Media Boot Behavior
>>>     To generate a file name when none is present in the FilePath, the
>>>     firmware must append a default file name in the form
>>>     \EFI\BOOT\BOOT{machine type short-name}.EFI ...
>>>
>>> 2) So (1) entails the hehavior that the user's preference of boot media
>>>      order should be determined by Boot#### and BootOrder variables.
>>>
>>> With this patch, the semantics mentioned above is fully implemented.
>>> For example, if you want to boot the system from USB and SCSI in this
>>> order,
>>> * define Boot0001 which contains only a device path to the USB device
>>>     (without any file path/name)
>>> * define Boot0002 which contains only a device path to the SCSI device,
>>> and
>>> * set BootOrder to Boot0001:Boot0002
>>>
>>> To avoid build error for sandbox, default file name "BOOTSANDBOX.efi"
>>> is defined even if it is out of scope of UEFI specification.
>>>
>>> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
>>> Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
>>> ---
>>> Changes in v5:
>>> - add default file name definition for SANDBOX to avoid build error
>>>
>>> Changes from original version:
>>> - create new include file "efi_default_filename.h" to
>>>     avoid conflict with config_distro_bootcmd.h
>>> - modify the target pointer of efi_free_pool(), expand_media_path() should
>>>     only free the pointer allocated by efi_dp_from_file() function.
>>>    include/config_distro_bootcmd.h | 14 +--------
>>>    include/efi_default_filename.h  | 33 ++++++++++++++++++++++
>>>    lib/efi_loader/efi_bootmgr.c    | 50 ++++++++++++++++++++++++++++++++-
>>>    3 files changed, 83 insertions(+), 14 deletions(-)
>>>    create mode 100644 include/efi_default_filename.h
>>>
>>> diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
>>> index c55023889c..6a3110f27b 100644
>>> --- a/include/config_distro_bootcmd.h
>>> +++ b/include/config_distro_bootcmd.h
>>> @@ -91,19 +91,7 @@
>>>    #endif
>>>
>>>    #ifdef CONFIG_EFI_LOADER
>>> -#if defined(CONFIG_ARM64)
>>> -#define BOOTEFI_NAME "bootaa64.efi"
>>> -#elif defined(CONFIG_ARM)
>>> -#define BOOTEFI_NAME "bootarm.efi"
>>> -#elif defined(CONFIG_X86_RUN_32BIT)
>>> -#define BOOTEFI_NAME "bootia32.efi"
>>> -#elif defined(CONFIG_X86_RUN_64BIT)
>>> -#define BOOTEFI_NAME "bootx64.efi"
>>> -#elif defined(CONFIG_ARCH_RV32I)
>>> -#define BOOTEFI_NAME "bootriscv32.efi"
>>> -#elif defined(CONFIG_ARCH_RV64I)
>>> -#define BOOTEFI_NAME "bootriscv64.efi"
>>> -#endif
>>> +#include <efi_default_filename.h>
>>>    #endif
>>>
>>>    #ifdef BOOTEFI_NAME
>>> diff --git a/include/efi_default_filename.h b/include/efi_default_filename.h
>>> new file mode 100644
>>> index 0000000000..cb2ef9e131
>>> --- /dev/null
>>> +++ b/include/efi_default_filename.h
>>> @@ -0,0 +1,33 @@
>>> +/* SPDX-License-Identifier: GPL-2.0+ */
>>> +/*
>>> + * Default boot file name when none is present in the FilePath.
>>> + * This is defined in the UEFI specification.
>>> + *
>>> + * Copyright (c) 2022, Linaro Limited
>>> + */
>>> +#ifndef _EFI_DEFAULT_FILENAME_H
>>> +#define _EFI_DEFAULT_FILENAME_H
>>> +
>>> +#if defined(CONFIG_ARM64)
>>> +#define BOOTEFI_NAME "BOOTAA64.EFI"
>>> +#elif defined(CONFIG_ARM)
>>> +#define BOOTEFI_NAME "BOOTARM.EFI"
>>> +#elif defined(CONFIG_X86_64)
>>> +#define BOOTEFI_NAME "BOOTX64.EFI"
>>> +#elif defined(CONFIG_X86)
>>> +#define BOOTEFI_NAME "BOOTIA32.EFI"
>>> +#elif defined(CONFIG_ARCH_RV32I)
>>> +#define BOOTEFI_NAME "BOOTRISCV32.EFI"
>>> +#elif defined(CONFIG_ARCH_RV64I)
>>> +#define BOOTEFI_NAME "BOOTRISCV64.EFI"
>>> +#elif defined(CONFIG_SANDBOX)
>>> +/*
>>> + * SANDBOX is not defined in UEFI specification, but
>>> + * this definition avoids build failure for SANDBOX.
>>> + */
>>> +#define BOOTEFI_NAME "BOOTSANDBOX.EFI"
>>
>> The sandbox should boot the default binary for the host architecture:
>>
>> #ifndef _EFI_DEFAULT_FILENAME_H
>> #define _EFI_DEFAULT_FILENAME_H
>>
>> #include <host_arch.h>
>>
>> #undef BOOTEFI_NAME
>>
>> #if HOST_ARCH == HOST_ARCH_X86_64
>> #define BOOTEFI_NAME "BOOTX64.EFI"
>> #endif
>>
>> #if HOST_ARCH == HOST_ARCH_X86
>> #define BOOTEFI_NAME "BOOTIA32.EFI"
>> #endif
>>
>> #if HOST_ARCH == HOST_ARCH_AARCH64
>> #define BOOTEFI_NAME "BOOTAA64.EFI"
>> #endif
>>
>> #if HOST_ARCH == HOST_ARCH_ARM
>> #define BOOTEFI_NAME "BOOTARM.EFI"
>> #endif
>>
>> #if HOST_ARCH == HOST_ARCH_RISCV32
>> #define BOOTEFI_NAME "BOOTRISCV32.EFI"
>> #endif
>>
>> #if HOST_ARCH == HOST_ARCH_RISCV64
>> #define BOOTEFI_NAME "BOOTRISCV64.EFI"
>> #endif
>>
>> #ifndef BOOTEFI_NAME
>> #error Unsupported UEFI architecture
>> #endif
>>
>> #endif
>
> Maybe sanbox is special, but using the host architecture for actual
> boards makes no sense.  I see this has made its way into master
> already, but when I cross-build for apple_m1_defconfig on an amd64
> machine I end up with:
>
>      $ strings ./lib/efi_loader/efi_bootmgr.o | grep BOOT
>      /EFI/BOOT/BOOTX64.EFI

Thanks for reporting the issue.

On Sandbox it should be the host architecture. on other defconfigs the
target architecture.

Best regards

Heinrich

>
> The original diff that used CONFIG_ARM64, CONFIG_ARM, etc, did this
> right.
Heinrich Schuchardt May 5, 2022, 12:35 p.m. UTC | #4
On 5/5/22 14:20, Heinrich Schuchardt wrote:
> On 5/5/22 14:05, Mark Kettenis wrote:
>>> Date: Fri, 29 Apr 2022 19:03:22 +0200
>>> From: Heinrich Schuchardt <xypron.glpk@gmx.de>
>>>
>>> On 4/28/22 10:09, Masahisa Kojima wrote:
>>>> From: AKASHI Takahiro <takahiro.akashi@linaro.org>
>>>>
>>>> Under the current implementation, booting from removable media using
>>>> a architecture-specific default image name, say BOOTAA64.EFI, is
>>>> supported only in distro_bootcmd script. See the commit 74522c898b35
>>>> ("efi_loader: Add distro boot script for removable media").
>>>>
>>>> This is, however, half-baked implementation because
>>>> 1) UEFI specification requires this feature to be implemented as part
>>>>      of Boot Manager's responsibility:
>>>>
>>>>     3 - Boot Manager
>>>>     3.5.1 Boot via the Simple File Protocol
>>>>     When booting via the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, the
>>>> FilePath will
>>>>     start with a device path that points to the device that
>>>> implements the
>>>>     EFI_SIMPLE_FILE_SYSTEM_PROTOCOL or the EFI_BLOCK_IO_PROTOCOL.
>>>> The next
>>>>     part of the FilePath may point to the file name, including
>>>>     subdirectories, which contain the bootable image. If the file
>>>> name is
>>>>     a null device path, the file name must be generated from the rules
>>>>     defined below.
>>>>     ...
>>>>     3.5.1.1 Removable Media Boot Behavior
>>>>     To generate a file name when none is present in the FilePath, the
>>>>     firmware must append a default file name in the form
>>>>     \EFI\BOOT\BOOT{machine type short-name}.EFI ...
>>>>
>>>> 2) So (1) entails the hehavior that the user's preference of boot media
>>>>      order should be determined by Boot#### and BootOrder variables.
>>>>
>>>> With this patch, the semantics mentioned above is fully implemented.
>>>> For example, if you want to boot the system from USB and SCSI in this
>>>> order,
>>>> * define Boot0001 which contains only a device path to the USB device
>>>>     (without any file path/name)
>>>> * define Boot0002 which contains only a device path to the SCSI device,
>>>> and
>>>> * set BootOrder to Boot0001:Boot0002
>>>>
>>>> To avoid build error for sandbox, default file name "BOOTSANDBOX.efi"
>>>> is defined even if it is out of scope of UEFI specification.
>>>>
>>>> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
>>>> Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
>>>> ---
>>>> Changes in v5:
>>>> - add default file name definition for SANDBOX to avoid build error
>>>>
>>>> Changes from original version:
>>>> - create new include file "efi_default_filename.h" to
>>>>     avoid conflict with config_distro_bootcmd.h
>>>> - modify the target pointer of efi_free_pool(), expand_media_path()
>>>> should
>>>>     only free the pointer allocated by efi_dp_from_file() function.
>>>>    include/config_distro_bootcmd.h | 14 +--------
>>>>    include/efi_default_filename.h  | 33 ++++++++++++++++++++++
>>>>    lib/efi_loader/efi_bootmgr.c    | 50
>>>> ++++++++++++++++++++++++++++++++-
>>>>    3 files changed, 83 insertions(+), 14 deletions(-)
>>>>    create mode 100644 include/efi_default_filename.h
>>>>
>>>> diff --git a/include/config_distro_bootcmd.h
>>>> b/include/config_distro_bootcmd.h
>>>> index c55023889c..6a3110f27b 100644
>>>> --- a/include/config_distro_bootcmd.h
>>>> +++ b/include/config_distro_bootcmd.h
>>>> @@ -91,19 +91,7 @@
>>>>    #endif
>>>>
>>>>    #ifdef CONFIG_EFI_LOADER
>>>> -#if defined(CONFIG_ARM64)
>>>> -#define BOOTEFI_NAME "bootaa64.efi"
>>>> -#elif defined(CONFIG_ARM)
>>>> -#define BOOTEFI_NAME "bootarm.efi"
>>>> -#elif defined(CONFIG_X86_RUN_32BIT)
>>>> -#define BOOTEFI_NAME "bootia32.efi"
>>>> -#elif defined(CONFIG_X86_RUN_64BIT)
>>>> -#define BOOTEFI_NAME "bootx64.efi"
>>>> -#elif defined(CONFIG_ARCH_RV32I)
>>>> -#define BOOTEFI_NAME "bootriscv32.efi"
>>>> -#elif defined(CONFIG_ARCH_RV64I)
>>>> -#define BOOTEFI_NAME "bootriscv64.efi"
>>>> -#endif
>>>> +#include <efi_default_filename.h>
>>>>    #endif
>>>>
>>>>    #ifdef BOOTEFI_NAME
>>>> diff --git a/include/efi_default_filename.h
>>>> b/include/efi_default_filename.h
>>>> new file mode 100644
>>>> index 0000000000..cb2ef9e131
>>>> --- /dev/null
>>>> +++ b/include/efi_default_filename.h
>>>> @@ -0,0 +1,33 @@
>>>> +/* SPDX-License-Identifier: GPL-2.0+ */
>>>> +/*
>>>> + * Default boot file name when none is present in the FilePath.
>>>> + * This is defined in the UEFI specification.
>>>> + *
>>>> + * Copyright (c) 2022, Linaro Limited
>>>> + */
>>>> +#ifndef _EFI_DEFAULT_FILENAME_H
>>>> +#define _EFI_DEFAULT_FILENAME_H
>>>> +
>>>> +#if defined(CONFIG_ARM64)
>>>> +#define BOOTEFI_NAME "BOOTAA64.EFI"
>>>> +#elif defined(CONFIG_ARM)
>>>> +#define BOOTEFI_NAME "BOOTARM.EFI"
>>>> +#elif defined(CONFIG_X86_64)
>>>> +#define BOOTEFI_NAME "BOOTX64.EFI"
>>>> +#elif defined(CONFIG_X86)
>>>> +#define BOOTEFI_NAME "BOOTIA32.EFI"
>>>> +#elif defined(CONFIG_ARCH_RV32I)
>>>> +#define BOOTEFI_NAME "BOOTRISCV32.EFI"
>>>> +#elif defined(CONFIG_ARCH_RV64I)
>>>> +#define BOOTEFI_NAME "BOOTRISCV64.EFI"
>>>> +#elif defined(CONFIG_SANDBOX)
>>>> +/*
>>>> + * SANDBOX is not defined in UEFI specification, but
>>>> + * this definition avoids build failure for SANDBOX.
>>>> + */
>>>> +#define BOOTEFI_NAME "BOOTSANDBOX.EFI"
>>>
>>> The sandbox should boot the default binary for the host architecture:
>>>
>>> #ifndef _EFI_DEFAULT_FILENAME_H
>>> #define _EFI_DEFAULT_FILENAME_H
>>>
>>> #include <host_arch.h>
>>>
>>> #undef BOOTEFI_NAME
>>>
>>> #if HOST_ARCH == HOST_ARCH_X86_64
>>> #define BOOTEFI_NAME "BOOTX64.EFI"
>>> #endif
>>>
>>> #if HOST_ARCH == HOST_ARCH_X86
>>> #define BOOTEFI_NAME "BOOTIA32.EFI"
>>> #endif
>>>
>>> #if HOST_ARCH == HOST_ARCH_AARCH64
>>> #define BOOTEFI_NAME "BOOTAA64.EFI"
>>> #endif
>>>
>>> #if HOST_ARCH == HOST_ARCH_ARM
>>> #define BOOTEFI_NAME "BOOTARM.EFI"
>>> #endif
>>>
>>> #if HOST_ARCH == HOST_ARCH_RISCV32
>>> #define BOOTEFI_NAME "BOOTRISCV32.EFI"
>>> #endif
>>>
>>> #if HOST_ARCH == HOST_ARCH_RISCV64
>>> #define BOOTEFI_NAME "BOOTRISCV64.EFI"
>>> #endif
>>>
>>> #ifndef BOOTEFI_NAME
>>> #error Unsupported UEFI architecture
>>> #endif
>>>
>>> #endif
>>
>> Maybe sanbox is special, but using the host architecture for actual
>> boards makes no sense.  I see this has made its way into master
>> already, but when I cross-build for apple_m1_defconfig on an amd64
>> machine I end up with:
>>
>>      $ strings ./lib/efi_loader/efi_bootmgr.o | grep BOOT
>>      /EFI/BOOT/BOOTX64.EFI
>
> Thanks for reporting the issue.
>
> On Sandbox it should be the host architecture. on other defconfigs the
> target architecture.

On Ubuntu 22.04:

git reset --hard 1739a6db5403d187902dcebca548de0644c8078f
make apple_m1_defconfig
CROSS_COMPILE=aarch64-linux-gnu- make -j16

$ strings ./lib/efi_loader/efi_bootmgr.o | grep BOOT
/EFI/BOOT/BOOTAA64.EFI
UCLASS_REBOOT_MODE
UCLASS_BOOTSTD
EFI_OBJECT_TYPE_U_BOOT_FIRMWARE
UCLASS_BOOTDEV
UCLASS_BOOTMETH
UCLASS_BOOTCOUN

$ strings u-boot | grep 'BOOT\S*\.EFI'
/EFI/BOOT/BOOTAA64.EFI

How can I reproduce your problem?
Is this BSD specific? Which distro are you running?

Best regards

Heinrich

>
> Best regards
>
> Heinrich
>
>>
>> The original diff that used CONFIG_ARM64, CONFIG_ARM, etc, did this
>> right.
>
Mark Kettenis May 5, 2022, 12:47 p.m. UTC | #5
> Date: Thu, 5 May 2022 14:05:04 +0200 (CEST)
> From: Mark Kettenis <mark.kettenis@xs4all.nl>
> 
> > Date: Fri, 29 Apr 2022 19:03:22 +0200
> > From: Heinrich Schuchardt <xypron.glpk@gmx.de>
> > 
> > On 4/28/22 10:09, Masahisa Kojima wrote:
> > > From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > >
> > > Under the current implementation, booting from removable media using
> > > a architecture-specific default image name, say BOOTAA64.EFI, is
> > > supported only in distro_bootcmd script. See the commit 74522c898b35
> > > ("efi_loader: Add distro boot script for removable media").
> > >
> > > This is, however, half-baked implementation because
> > > 1) UEFI specification requires this feature to be implemented as part
> > >     of Boot Manager's responsibility:
> > >
> > >    3 - Boot Manager
> > >    3.5.1 Boot via the Simple File Protocol
> > >    When booting via the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, the FilePath will
> > >    start with a device path that points to the device that implements the
> > >    EFI_SIMPLE_FILE_SYSTEM_PROTOCOL or the EFI_BLOCK_IO_PROTOCOL. The next
> > >    part of the FilePath may point to the file name, including
> > >    subdirectories, which contain the bootable image. If the file name is
> > >    a null device path, the file name must be generated from the rules
> > >    defined below.
> > >    ...
> > >    3.5.1.1 Removable Media Boot Behavior
> > >    To generate a file name when none is present in the FilePath, the
> > >    firmware must append a default file name in the form
> > >    \EFI\BOOT\BOOT{machine type short-name}.EFI ...
> > >
> > > 2) So (1) entails the hehavior that the user's preference of boot media
> > >     order should be determined by Boot#### and BootOrder variables.
> > >
> > > With this patch, the semantics mentioned above is fully implemented.
> > > For example, if you want to boot the system from USB and SCSI in this
> > > order,
> > > * define Boot0001 which contains only a device path to the USB device
> > >    (without any file path/name)
> > > * define Boot0002 which contains only a device path to the SCSI device,
> > > and
> > > * set BootOrder to Boot0001:Boot0002
> > >
> > > To avoid build error for sandbox, default file name "BOOTSANDBOX.efi"
> > > is defined even if it is out of scope of UEFI specification.
> > >
> > > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > > Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
> > > ---
> > > Changes in v5:
> > > - add default file name definition for SANDBOX to avoid build error
> > >
> > > Changes from original version:
> > > - create new include file "efi_default_filename.h" to
> > >    avoid conflict with config_distro_bootcmd.h
> > > - modify the target pointer of efi_free_pool(), expand_media_path() should
> > >    only free the pointer allocated by efi_dp_from_file() function.
> > >   include/config_distro_bootcmd.h | 14 +--------
> > >   include/efi_default_filename.h  | 33 ++++++++++++++++++++++
> > >   lib/efi_loader/efi_bootmgr.c    | 50 ++++++++++++++++++++++++++++++++-
> > >   3 files changed, 83 insertions(+), 14 deletions(-)
> > >   create mode 100644 include/efi_default_filename.h
> > >
> > > diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
> > > index c55023889c..6a3110f27b 100644
> > > --- a/include/config_distro_bootcmd.h
> > > +++ b/include/config_distro_bootcmd.h
> > > @@ -91,19 +91,7 @@
> > >   #endif
> > >
> > >   #ifdef CONFIG_EFI_LOADER
> > > -#if defined(CONFIG_ARM64)
> > > -#define BOOTEFI_NAME "bootaa64.efi"
> > > -#elif defined(CONFIG_ARM)
> > > -#define BOOTEFI_NAME "bootarm.efi"
> > > -#elif defined(CONFIG_X86_RUN_32BIT)
> > > -#define BOOTEFI_NAME "bootia32.efi"
> > > -#elif defined(CONFIG_X86_RUN_64BIT)
> > > -#define BOOTEFI_NAME "bootx64.efi"
> > > -#elif defined(CONFIG_ARCH_RV32I)
> > > -#define BOOTEFI_NAME "bootriscv32.efi"
> > > -#elif defined(CONFIG_ARCH_RV64I)
> > > -#define BOOTEFI_NAME "bootriscv64.efi"
> > > -#endif
> > > +#include <efi_default_filename.h>
> > >   #endif
> > >
> > >   #ifdef BOOTEFI_NAME
> > > diff --git a/include/efi_default_filename.h b/include/efi_default_filename.h
> > > new file mode 100644
> > > index 0000000000..cb2ef9e131
> > > --- /dev/null
> > > +++ b/include/efi_default_filename.h
> > > @@ -0,0 +1,33 @@
> > > +/* SPDX-License-Identifier: GPL-2.0+ */
> > > +/*
> > > + * Default boot file name when none is present in the FilePath.
> > > + * This is defined in the UEFI specification.
> > > + *
> > > + * Copyright (c) 2022, Linaro Limited
> > > + */
> > > +#ifndef _EFI_DEFAULT_FILENAME_H
> > > +#define _EFI_DEFAULT_FILENAME_H
> > > +
> > > +#if defined(CONFIG_ARM64)
> > > +#define BOOTEFI_NAME "BOOTAA64.EFI"
> > > +#elif defined(CONFIG_ARM)
> > > +#define BOOTEFI_NAME "BOOTARM.EFI"
> > > +#elif defined(CONFIG_X86_64)
> > > +#define BOOTEFI_NAME "BOOTX64.EFI"
> > > +#elif defined(CONFIG_X86)
> > > +#define BOOTEFI_NAME "BOOTIA32.EFI"
> > > +#elif defined(CONFIG_ARCH_RV32I)
> > > +#define BOOTEFI_NAME "BOOTRISCV32.EFI"
> > > +#elif defined(CONFIG_ARCH_RV64I)
> > > +#define BOOTEFI_NAME "BOOTRISCV64.EFI"
> > > +#elif defined(CONFIG_SANDBOX)
> > > +/*
> > > + * SANDBOX is not defined in UEFI specification, but
> > > + * this definition avoids build failure for SANDBOX.
> > > + */
> > > +#define BOOTEFI_NAME "BOOTSANDBOX.EFI"
> > 
> > The sandbox should boot the default binary for the host architecture:
> > 
> > #ifndef _EFI_DEFAULT_FILENAME_H
> > #define _EFI_DEFAULT_FILENAME_H
> > 
> > #include <host_arch.h>
> > 
> > #undef BOOTEFI_NAME
> > 
> > #if HOST_ARCH == HOST_ARCH_X86_64
> > #define BOOTEFI_NAME "BOOTX64.EFI"
> > #endif
> > 
> > #if HOST_ARCH == HOST_ARCH_X86
> > #define BOOTEFI_NAME "BOOTIA32.EFI"
> > #endif
> > 
> > #if HOST_ARCH == HOST_ARCH_AARCH64
> > #define BOOTEFI_NAME "BOOTAA64.EFI"
> > #endif
> > 
> > #if HOST_ARCH == HOST_ARCH_ARM
> > #define BOOTEFI_NAME "BOOTARM.EFI"
> > #endif
> > 
> > #if HOST_ARCH == HOST_ARCH_RISCV32
> > #define BOOTEFI_NAME "BOOTRISCV32.EFI"
> > #endif
> > 
> > #if HOST_ARCH == HOST_ARCH_RISCV64
> > #define BOOTEFI_NAME "BOOTRISCV64.EFI"
> > #endif
> > 
> > #ifndef BOOTEFI_NAME
> > #error Unsupported UEFI architecture
> > #endif
> > 
> > #endif
> 
> Maybe sanbox is special, but using the host architecture for actual
> boards makes no sense.  I see this has made its way into master
> already, but when I cross-build for apple_m1_defconfig on an amd64
> machine I end up with:
> 
>     $ strings ./lib/efi_loader/efi_bootmgr.o | grep BOOT
>     /EFI/BOOT/BOOTX64.EFI
> 
> The original diff that used CONFIG_ARM64, CONFIG_ARM, etc, did this
> right.

Hmm, forget about that.  The problem is in the sed expression in the
toplevel Makefile that is used to MK_ARCH that ends up setting
HOST_ARCH incorrectly.  Using a variable named HOST_ARCH to hold the
target architecture doesn't help understanding what's going wrong here
of course...
Mark Kettenis May 5, 2022, 1:25 p.m. UTC | #6
> Date: Thu, 5 May 2022 14:35:36 +0200
> From: Heinrich Schuchardt <xypron.glpk@gmx.de>
> 
> On 5/5/22 14:20, Heinrich Schuchardt wrote:
> > On 5/5/22 14:05, Mark Kettenis wrote:
> >>> Date: Fri, 29 Apr 2022 19:03:22 +0200
> >>> From: Heinrich Schuchardt <xypron.glpk@gmx.de>
> >>>
> >>> On 4/28/22 10:09, Masahisa Kojima wrote:
> >>>> From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> >>>>
> >>>> Under the current implementation, booting from removable media using
> >>>> a architecture-specific default image name, say BOOTAA64.EFI, is
> >>>> supported only in distro_bootcmd script. See the commit 74522c898b35
> >>>> ("efi_loader: Add distro boot script for removable media").
> >>>>
> >>>> This is, however, half-baked implementation because
> >>>> 1) UEFI specification requires this feature to be implemented as part
> >>>>      of Boot Manager's responsibility:
> >>>>
> >>>>     3 - Boot Manager
> >>>>     3.5.1 Boot via the Simple File Protocol
> >>>>     When booting via the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, the
> >>>> FilePath will
> >>>>     start with a device path that points to the device that
> >>>> implements the
> >>>>     EFI_SIMPLE_FILE_SYSTEM_PROTOCOL or the EFI_BLOCK_IO_PROTOCOL.
> >>>> The next
> >>>>     part of the FilePath may point to the file name, including
> >>>>     subdirectories, which contain the bootable image. If the file
> >>>> name is
> >>>>     a null device path, the file name must be generated from the rules
> >>>>     defined below.
> >>>>     ...
> >>>>     3.5.1.1 Removable Media Boot Behavior
> >>>>     To generate a file name when none is present in the FilePath, the
> >>>>     firmware must append a default file name in the form
> >>>>     \EFI\BOOT\BOOT{machine type short-name}.EFI ...
> >>>>
> >>>> 2) So (1) entails the hehavior that the user's preference of boot media
> >>>>      order should be determined by Boot#### and BootOrder variables.
> >>>>
> >>>> With this patch, the semantics mentioned above is fully implemented.
> >>>> For example, if you want to boot the system from USB and SCSI in this
> >>>> order,
> >>>> * define Boot0001 which contains only a device path to the USB device
> >>>>     (without any file path/name)
> >>>> * define Boot0002 which contains only a device path to the SCSI device,
> >>>> and
> >>>> * set BootOrder to Boot0001:Boot0002
> >>>>
> >>>> To avoid build error for sandbox, default file name "BOOTSANDBOX.efi"
> >>>> is defined even if it is out of scope of UEFI specification.
> >>>>
> >>>> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> >>>> Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
> >>>> ---
> >>>> Changes in v5:
> >>>> - add default file name definition for SANDBOX to avoid build error
> >>>>
> >>>> Changes from original version:
> >>>> - create new include file "efi_default_filename.h" to
> >>>>     avoid conflict with config_distro_bootcmd.h
> >>>> - modify the target pointer of efi_free_pool(), expand_media_path()
> >>>> should
> >>>>     only free the pointer allocated by efi_dp_from_file() function.
> >>>>    include/config_distro_bootcmd.h | 14 +--------
> >>>>    include/efi_default_filename.h  | 33 ++++++++++++++++++++++
> >>>>    lib/efi_loader/efi_bootmgr.c    | 50
> >>>> ++++++++++++++++++++++++++++++++-
> >>>>    3 files changed, 83 insertions(+), 14 deletions(-)
> >>>>    create mode 100644 include/efi_default_filename.h
> >>>>
> >>>> diff --git a/include/config_distro_bootcmd.h
> >>>> b/include/config_distro_bootcmd.h
> >>>> index c55023889c..6a3110f27b 100644
> >>>> --- a/include/config_distro_bootcmd.h
> >>>> +++ b/include/config_distro_bootcmd.h
> >>>> @@ -91,19 +91,7 @@
> >>>>    #endif
> >>>>
> >>>>    #ifdef CONFIG_EFI_LOADER
> >>>> -#if defined(CONFIG_ARM64)
> >>>> -#define BOOTEFI_NAME "bootaa64.efi"
> >>>> -#elif defined(CONFIG_ARM)
> >>>> -#define BOOTEFI_NAME "bootarm.efi"
> >>>> -#elif defined(CONFIG_X86_RUN_32BIT)
> >>>> -#define BOOTEFI_NAME "bootia32.efi"
> >>>> -#elif defined(CONFIG_X86_RUN_64BIT)
> >>>> -#define BOOTEFI_NAME "bootx64.efi"
> >>>> -#elif defined(CONFIG_ARCH_RV32I)
> >>>> -#define BOOTEFI_NAME "bootriscv32.efi"
> >>>> -#elif defined(CONFIG_ARCH_RV64I)
> >>>> -#define BOOTEFI_NAME "bootriscv64.efi"
> >>>> -#endif
> >>>> +#include <efi_default_filename.h>
> >>>>    #endif
> >>>>
> >>>>    #ifdef BOOTEFI_NAME
> >>>> diff --git a/include/efi_default_filename.h
> >>>> b/include/efi_default_filename.h
> >>>> new file mode 100644
> >>>> index 0000000000..cb2ef9e131
> >>>> --- /dev/null
> >>>> +++ b/include/efi_default_filename.h
> >>>> @@ -0,0 +1,33 @@
> >>>> +/* SPDX-License-Identifier: GPL-2.0+ */
> >>>> +/*
> >>>> + * Default boot file name when none is present in the FilePath.
> >>>> + * This is defined in the UEFI specification.
> >>>> + *
> >>>> + * Copyright (c) 2022, Linaro Limited
> >>>> + */
> >>>> +#ifndef _EFI_DEFAULT_FILENAME_H
> >>>> +#define _EFI_DEFAULT_FILENAME_H
> >>>> +
> >>>> +#if defined(CONFIG_ARM64)
> >>>> +#define BOOTEFI_NAME "BOOTAA64.EFI"
> >>>> +#elif defined(CONFIG_ARM)
> >>>> +#define BOOTEFI_NAME "BOOTARM.EFI"
> >>>> +#elif defined(CONFIG_X86_64)
> >>>> +#define BOOTEFI_NAME "BOOTX64.EFI"
> >>>> +#elif defined(CONFIG_X86)
> >>>> +#define BOOTEFI_NAME "BOOTIA32.EFI"
> >>>> +#elif defined(CONFIG_ARCH_RV32I)
> >>>> +#define BOOTEFI_NAME "BOOTRISCV32.EFI"
> >>>> +#elif defined(CONFIG_ARCH_RV64I)
> >>>> +#define BOOTEFI_NAME "BOOTRISCV64.EFI"
> >>>> +#elif defined(CONFIG_SANDBOX)
> >>>> +/*
> >>>> + * SANDBOX is not defined in UEFI specification, but
> >>>> + * this definition avoids build failure for SANDBOX.
> >>>> + */
> >>>> +#define BOOTEFI_NAME "BOOTSANDBOX.EFI"
> >>>
> >>> The sandbox should boot the default binary for the host architecture:
> >>>
> >>> #ifndef _EFI_DEFAULT_FILENAME_H
> >>> #define _EFI_DEFAULT_FILENAME_H
> >>>
> >>> #include <host_arch.h>
> >>>
> >>> #undef BOOTEFI_NAME
> >>>
> >>> #if HOST_ARCH == HOST_ARCH_X86_64
> >>> #define BOOTEFI_NAME "BOOTX64.EFI"
> >>> #endif
> >>>
> >>> #if HOST_ARCH == HOST_ARCH_X86
> >>> #define BOOTEFI_NAME "BOOTIA32.EFI"
> >>> #endif
> >>>
> >>> #if HOST_ARCH == HOST_ARCH_AARCH64
> >>> #define BOOTEFI_NAME "BOOTAA64.EFI"
> >>> #endif
> >>>
> >>> #if HOST_ARCH == HOST_ARCH_ARM
> >>> #define BOOTEFI_NAME "BOOTARM.EFI"
> >>> #endif
> >>>
> >>> #if HOST_ARCH == HOST_ARCH_RISCV32
> >>> #define BOOTEFI_NAME "BOOTRISCV32.EFI"
> >>> #endif
> >>>
> >>> #if HOST_ARCH == HOST_ARCH_RISCV64
> >>> #define BOOTEFI_NAME "BOOTRISCV64.EFI"
> >>> #endif
> >>>
> >>> #ifndef BOOTEFI_NAME
> >>> #error Unsupported UEFI architecture
> >>> #endif
> >>>
> >>> #endif
> >>
> >> Maybe sanbox is special, but using the host architecture for actual
> >> boards makes no sense.  I see this has made its way into master
> >> already, but when I cross-build for apple_m1_defconfig on an amd64
> >> machine I end up with:
> >>
> >>      $ strings ./lib/efi_loader/efi_bootmgr.o | grep BOOT
> >>      /EFI/BOOT/BOOTX64.EFI
> >
> > Thanks for reporting the issue.
> >
> > On Sandbox it should be the host architecture. on other defconfigs the
> > target architecture.
> 
> On Ubuntu 22.04:
> 
> git reset --hard 1739a6db5403d187902dcebca548de0644c8078f
> make apple_m1_defconfig
> CROSS_COMPILE=aarch64-linux-gnu- make -j16
> 
> $ strings ./lib/efi_loader/efi_bootmgr.o | grep BOOT
> /EFI/BOOT/BOOTAA64.EFI
> UCLASS_REBOOT_MODE
> UCLASS_BOOTSTD
> EFI_OBJECT_TYPE_U_BOOT_FIRMWARE
> UCLASS_BOOTDEV
> UCLASS_BOOTMETH
> UCLASS_BOOTCOUN
> 
> $ strings u-boot | grep 'BOOT\S*\.EFI'
> /EFI/BOOT/BOOTAA64.EFI
> 
> How can I reproduce your problem?
> Is this BSD specific? Which distro are you running?

Yes, I'm always building on OpenBSD.  And the probablem is the use of
non-portable GNU sed extensions \s and \S.  Replacing those with
[[:space:]] and [^[:space:]] as in the diff below seems to work.
Decoding chicken scratches is alway fun...

This has been broken for a while, but didn't cause any build issues
until now.  I'll send a proper patch to the mailing list.


diff --git a/Makefile b/Makefile
index ea80f00716..6eceeb35b4 100644
--- a/Makefile
+++ b/Makefile
@@ -21,7 +21,7 @@ include include/host_arch.h
 ifeq ("", "$(CROSS_COMPILE)")
   MK_ARCH="${shell uname -m}"
 else
-  MK_ARCH="${shell echo $(CROSS_COMPILE) | sed -n 's/^\s*\([^\/]*\/\)*\([^-]*\)-\S*/\2/p'}"
+  MK_ARCH="${shell echo $(CROSS_COMPILE) | sed -n 's/^[[:space:]]*\([^\/]*\/\)*\([^-]*\)-[^[:space:]]*/\2/p'}"
 endif
 unexport HOST_ARCH
 ifeq ("x86_64", $(MK_ARCH))
AKASHI Takahiro May 12, 2022, 9:12 a.m. UTC | #7
Heinrich,

On Thu, May 05, 2022 at 02:47:35PM +0200, Mark Kettenis wrote:
> > Date: Thu, 5 May 2022 14:05:04 +0200 (CEST)
> > From: Mark Kettenis <mark.kettenis@xs4all.nl>
> > 
> > > Date: Fri, 29 Apr 2022 19:03:22 +0200
> > > From: Heinrich Schuchardt <xypron.glpk@gmx.de>
> > > 
> > > On 4/28/22 10:09, Masahisa Kojima wrote:
> > > > From: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > > >
> > > > Under the current implementation, booting from removable media using
> > > > a architecture-specific default image name, say BOOTAA64.EFI, is
> > > > supported only in distro_bootcmd script. See the commit 74522c898b35
> > > > ("efi_loader: Add distro boot script for removable media").
> > > >
> > > > This is, however, half-baked implementation because
> > > > 1) UEFI specification requires this feature to be implemented as part
> > > >     of Boot Manager's responsibility:
> > > >
> > > >    3 - Boot Manager
> > > >    3.5.1 Boot via the Simple File Protocol
> > > >    When booting via the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, the FilePath will
> > > >    start with a device path that points to the device that implements the
> > > >    EFI_SIMPLE_FILE_SYSTEM_PROTOCOL or the EFI_BLOCK_IO_PROTOCOL. The next
> > > >    part of the FilePath may point to the file name, including
> > > >    subdirectories, which contain the bootable image. If the file name is
> > > >    a null device path, the file name must be generated from the rules
> > > >    defined below.
> > > >    ...
> > > >    3.5.1.1 Removable Media Boot Behavior
> > > >    To generate a file name when none is present in the FilePath, the
> > > >    firmware must append a default file name in the form
> > > >    \EFI\BOOT\BOOT{machine type short-name}.EFI ...
> > > >
> > > > 2) So (1) entails the hehavior that the user's preference of boot media
> > > >     order should be determined by Boot#### and BootOrder variables.
> > > >
> > > > With this patch, the semantics mentioned above is fully implemented.
> > > > For example, if you want to boot the system from USB and SCSI in this
> > > > order,
> > > > * define Boot0001 which contains only a device path to the USB device
> > > >    (without any file path/name)
> > > > * define Boot0002 which contains only a device path to the SCSI device,
> > > > and
> > > > * set BootOrder to Boot0001:Boot0002
> > > >
> > > > To avoid build error for sandbox, default file name "BOOTSANDBOX.efi"
> > > > is defined even if it is out of scope of UEFI specification.
> > > >
> > > > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > > > Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
> > > > ---
> > > > Changes in v5:
> > > > - add default file name definition for SANDBOX to avoid build error
> > > >
> > > > Changes from original version:
> > > > - create new include file "efi_default_filename.h" to
> > > >    avoid conflict with config_distro_bootcmd.h
> > > > - modify the target pointer of efi_free_pool(), expand_media_path() should
> > > >    only free the pointer allocated by efi_dp_from_file() function.
> > > >   include/config_distro_bootcmd.h | 14 +--------
> > > >   include/efi_default_filename.h  | 33 ++++++++++++++++++++++
> > > >   lib/efi_loader/efi_bootmgr.c    | 50 ++++++++++++++++++++++++++++++++-
> > > >   3 files changed, 83 insertions(+), 14 deletions(-)
> > > >   create mode 100644 include/efi_default_filename.h
> > > >
> > > > diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
> > > > index c55023889c..6a3110f27b 100644
> > > > --- a/include/config_distro_bootcmd.h
> > > > +++ b/include/config_distro_bootcmd.h
> > > > @@ -91,19 +91,7 @@
> > > >   #endif
> > > >
> > > >   #ifdef CONFIG_EFI_LOADER
> > > > -#if defined(CONFIG_ARM64)
> > > > -#define BOOTEFI_NAME "bootaa64.efi"
> > > > -#elif defined(CONFIG_ARM)
> > > > -#define BOOTEFI_NAME "bootarm.efi"
> > > > -#elif defined(CONFIG_X86_RUN_32BIT)
> > > > -#define BOOTEFI_NAME "bootia32.efi"
> > > > -#elif defined(CONFIG_X86_RUN_64BIT)
> > > > -#define BOOTEFI_NAME "bootx64.efi"
> > > > -#elif defined(CONFIG_ARCH_RV32I)
> > > > -#define BOOTEFI_NAME "bootriscv32.efi"
> > > > -#elif defined(CONFIG_ARCH_RV64I)
> > > > -#define BOOTEFI_NAME "bootriscv64.efi"
> > > > -#endif
> > > > +#include <efi_default_filename.h>
> > > >   #endif
> > > >
> > > >   #ifdef BOOTEFI_NAME
> > > > diff --git a/include/efi_default_filename.h b/include/efi_default_filename.h
> > > > new file mode 100644
> > > > index 0000000000..cb2ef9e131
> > > > --- /dev/null
> > > > +++ b/include/efi_default_filename.h
> > > > @@ -0,0 +1,33 @@
> > > > +/* SPDX-License-Identifier: GPL-2.0+ */
> > > > +/*
> > > > + * Default boot file name when none is present in the FilePath.
> > > > + * This is defined in the UEFI specification.
> > > > + *
> > > > + * Copyright (c) 2022, Linaro Limited
> > > > + */
> > > > +#ifndef _EFI_DEFAULT_FILENAME_H
> > > > +#define _EFI_DEFAULT_FILENAME_H
> > > > +
> > > > +#if defined(CONFIG_ARM64)
> > > > +#define BOOTEFI_NAME "BOOTAA64.EFI"
> > > > +#elif defined(CONFIG_ARM)
> > > > +#define BOOTEFI_NAME "BOOTARM.EFI"
> > > > +#elif defined(CONFIG_X86_64)
> > > > +#define BOOTEFI_NAME "BOOTX64.EFI"
> > > > +#elif defined(CONFIG_X86)
> > > > +#define BOOTEFI_NAME "BOOTIA32.EFI"
> > > > +#elif defined(CONFIG_ARCH_RV32I)
> > > > +#define BOOTEFI_NAME "BOOTRISCV32.EFI"
> > > > +#elif defined(CONFIG_ARCH_RV64I)
> > > > +#define BOOTEFI_NAME "BOOTRISCV64.EFI"
> > > > +#elif defined(CONFIG_SANDBOX)
> > > > +/*
> > > > + * SANDBOX is not defined in UEFI specification, but
> > > > + * this definition avoids build failure for SANDBOX.
> > > > + */
> > > > +#define BOOTEFI_NAME "BOOTSANDBOX.EFI"
> > > 
> > > The sandbox should boot the default binary for the host architecture:
> > > 
> > > #ifndef _EFI_DEFAULT_FILENAME_H
> > > #define _EFI_DEFAULT_FILENAME_H
> > > 
> > > #include <host_arch.h>
> > > 
> > > #undef BOOTEFI_NAME
> > > 
> > > #if HOST_ARCH == HOST_ARCH_X86_64
> > > #define BOOTEFI_NAME "BOOTX64.EFI"
> > > #endif
> > > 
> > > #if HOST_ARCH == HOST_ARCH_X86
> > > #define BOOTEFI_NAME "BOOTIA32.EFI"
> > > #endif
> > > 
> > > #if HOST_ARCH == HOST_ARCH_AARCH64
> > > #define BOOTEFI_NAME "BOOTAA64.EFI"
> > > #endif
> > > 
> > > #if HOST_ARCH == HOST_ARCH_ARM
> > > #define BOOTEFI_NAME "BOOTARM.EFI"
> > > #endif
> > > 
> > > #if HOST_ARCH == HOST_ARCH_RISCV32
> > > #define BOOTEFI_NAME "BOOTRISCV32.EFI"
> > > #endif
> > > 
> > > #if HOST_ARCH == HOST_ARCH_RISCV64
> > > #define BOOTEFI_NAME "BOOTRISCV64.EFI"
> > > #endif
> > > 
> > > #ifndef BOOTEFI_NAME
> > > #error Unsupported UEFI architecture
> > > #endif
> > > 
> > > #endif
> > 
> > Maybe sanbox is special, but using the host architecture for actual
> > boards makes no sense.  I see this has made its way into master
> > already, but when I cross-build for apple_m1_defconfig on an amd64
> > machine I end up with:
> > 
> >     $ strings ./lib/efi_loader/efi_bootmgr.o | grep BOOT
> >     /EFI/BOOT/BOOTX64.EFI
> > 
> > The original diff that used CONFIG_ARM64, CONFIG_ARM, etc, did this
> > right.
> 
> Hmm, forget about that.  The problem is in the sed expression in the
> toplevel Makefile that is used to MK_ARCH that ends up setting
> HOST_ARCH incorrectly.  Using a variable named HOST_ARCH to hold the
> target architecture doesn't help understanding what's going wrong here
> of course...

I can nod to Mark's comment here.
Even though HOST_ARCH might work, it's quite confusing.
Apparently it looks wrong as Mark said.

Please address this comment properly as you modified my patch.

What I basically recommend is:
* In (top-dir)/Makefile
  - s/HOST_ARCH/MK_ARCH/g
  - add
      if (CONFIG_SANDBOX)
          HOST_ARCH = $(MK_ARCH)
  - remove "undefine MK_ARCH"
* In efi_default_filename.h
  - s/HOST_ARCH/MK_ARCH/g

This way, HOST_ARCH is only used in sandbox-related code.

-Takahiro Akashi
Heinrich Schuchardt May 12, 2022, 10:34 a.m. UTC | #8
Am 12. Mai 2022 11:12:47 MESZ schrieb AKASHI Takahiro <takahiro.akashi@linaro.org>:
>Heinrich,
>
>On Thu, May 05, 2022 at 02:47:35PM +0200, Mark Kettenis wrote:
>> > Date: Thu, 5 May 2022 14:05:04 +0200 (CEST)
>> > From: Mark Kettenis <mark.kettenis@xs4all.nl>
>> > 
>> > > Date: Fri, 29 Apr 2022 19:03:22 +0200
>> > > From: Heinrich Schuchardt <xypron.glpk@gmx.de>
>> > > 
>> > > On 4/28/22 10:09, Masahisa Kojima wrote:
>> > > > From: AKASHI Takahiro <takahiro.akashi@linaro.org>
>> > > >
>> > > > Under the current implementation, booting from removable media using
>> > > > a architecture-specific default image name, say BOOTAA64.EFI, is
>> > > > supported only in distro_bootcmd script. See the commit 74522c898b35
>> > > > ("efi_loader: Add distro boot script for removable media").
>> > > >
>> > > > This is, however, half-baked implementation because
>> > > > 1) UEFI specification requires this feature to be implemented as part
>> > > >     of Boot Manager's responsibility:
>> > > >
>> > > >    3 - Boot Manager
>> > > >    3.5.1 Boot via the Simple File Protocol
>> > > >    When booting via the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, the FilePath will
>> > > >    start with a device path that points to the device that implements the
>> > > >    EFI_SIMPLE_FILE_SYSTEM_PROTOCOL or the EFI_BLOCK_IO_PROTOCOL. The next
>> > > >    part of the FilePath may point to the file name, including
>> > > >    subdirectories, which contain the bootable image. If the file name is
>> > > >    a null device path, the file name must be generated from the rules
>> > > >    defined below.
>> > > >    ...
>> > > >    3.5.1.1 Removable Media Boot Behavior
>> > > >    To generate a file name when none is present in the FilePath, the
>> > > >    firmware must append a default file name in the form
>> > > >    \EFI\BOOT\BOOT{machine type short-name}.EFI ...
>> > > >
>> > > > 2) So (1) entails the hehavior that the user's preference of boot media
>> > > >     order should be determined by Boot#### and BootOrder variables.
>> > > >
>> > > > With this patch, the semantics mentioned above is fully implemented.
>> > > > For example, if you want to boot the system from USB and SCSI in this
>> > > > order,
>> > > > * define Boot0001 which contains only a device path to the USB device
>> > > >    (without any file path/name)
>> > > > * define Boot0002 which contains only a device path to the SCSI device,
>> > > > and
>> > > > * set BootOrder to Boot0001:Boot0002
>> > > >
>> > > > To avoid build error for sandbox, default file name "BOOTSANDBOX.efi"
>> > > > is defined even if it is out of scope of UEFI specification.
>> > > >
>> > > > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
>> > > > Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
>> > > > ---
>> > > > Changes in v5:
>> > > > - add default file name definition for SANDBOX to avoid build error
>> > > >
>> > > > Changes from original version:
>> > > > - create new include file "efi_default_filename.h" to
>> > > >    avoid conflict with config_distro_bootcmd.h
>> > > > - modify the target pointer of efi_free_pool(), expand_media_path() should
>> > > >    only free the pointer allocated by efi_dp_from_file() function.
>> > > >   include/config_distro_bootcmd.h | 14 +--------
>> > > >   include/efi_default_filename.h  | 33 ++++++++++++++++++++++
>> > > >   lib/efi_loader/efi_bootmgr.c    | 50 ++++++++++++++++++++++++++++++++-
>> > > >   3 files changed, 83 insertions(+), 14 deletions(-)
>> > > >   create mode 100644 include/efi_default_filename.h
>> > > >
>> > > > diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
>> > > > index c55023889c..6a3110f27b 100644
>> > > > --- a/include/config_distro_bootcmd.h
>> > > > +++ b/include/config_distro_bootcmd.h
>> > > > @@ -91,19 +91,7 @@
>> > > >   #endif
>> > > >
>> > > >   #ifdef CONFIG_EFI_LOADER
>> > > > -#if defined(CONFIG_ARM64)
>> > > > -#define BOOTEFI_NAME "bootaa64.efi"
>> > > > -#elif defined(CONFIG_ARM)
>> > > > -#define BOOTEFI_NAME "bootarm.efi"
>> > > > -#elif defined(CONFIG_X86_RUN_32BIT)
>> > > > -#define BOOTEFI_NAME "bootia32.efi"
>> > > > -#elif defined(CONFIG_X86_RUN_64BIT)
>> > > > -#define BOOTEFI_NAME "bootx64.efi"
>> > > > -#elif defined(CONFIG_ARCH_RV32I)
>> > > > -#define BOOTEFI_NAME "bootriscv32.efi"
>> > > > -#elif defined(CONFIG_ARCH_RV64I)
>> > > > -#define BOOTEFI_NAME "bootriscv64.efi"
>> > > > -#endif
>> > > > +#include <efi_default_filename.h>
>> > > >   #endif
>> > > >
>> > > >   #ifdef BOOTEFI_NAME
>> > > > diff --git a/include/efi_default_filename.h b/include/efi_default_filename.h
>> > > > new file mode 100644
>> > > > index 0000000000..cb2ef9e131
>> > > > --- /dev/null
>> > > > +++ b/include/efi_default_filename.h
>> > > > @@ -0,0 +1,33 @@
>> > > > +/* SPDX-License-Identifier: GPL-2.0+ */
>> > > > +/*
>> > > > + * Default boot file name when none is present in the FilePath.
>> > > > + * This is defined in the UEFI specification.
>> > > > + *
>> > > > + * Copyright (c) 2022, Linaro Limited
>> > > > + */
>> > > > +#ifndef _EFI_DEFAULT_FILENAME_H
>> > > > +#define _EFI_DEFAULT_FILENAME_H
>> > > > +
>> > > > +#if defined(CONFIG_ARM64)
>> > > > +#define BOOTEFI_NAME "BOOTAA64.EFI"
>> > > > +#elif defined(CONFIG_ARM)
>> > > > +#define BOOTEFI_NAME "BOOTARM.EFI"
>> > > > +#elif defined(CONFIG_X86_64)
>> > > > +#define BOOTEFI_NAME "BOOTX64.EFI"
>> > > > +#elif defined(CONFIG_X86)
>> > > > +#define BOOTEFI_NAME "BOOTIA32.EFI"
>> > > > +#elif defined(CONFIG_ARCH_RV32I)
>> > > > +#define BOOTEFI_NAME "BOOTRISCV32.EFI"
>> > > > +#elif defined(CONFIG_ARCH_RV64I)
>> > > > +#define BOOTEFI_NAME "BOOTRISCV64.EFI"
>> > > > +#elif defined(CONFIG_SANDBOX)
>> > > > +/*
>> > > > + * SANDBOX is not defined in UEFI specification, but
>> > > > + * this definition avoids build failure for SANDBOX.
>> > > > + */
>> > > > +#define BOOTEFI_NAME "BOOTSANDBOX.EFI"
>> > > 
>> > > The sandbox should boot the default binary for the host architecture:
>> > > 
>> > > #ifndef _EFI_DEFAULT_FILENAME_H
>> > > #define _EFI_DEFAULT_FILENAME_H
>> > > 
>> > > #include <host_arch.h>
>> > > 
>> > > #undef BOOTEFI_NAME
>> > > 
>> > > #if HOST_ARCH == HOST_ARCH_X86_64
>> > > #define BOOTEFI_NAME "BOOTX64.EFI"
>> > > #endif
>> > > 
>> > > #if HOST_ARCH == HOST_ARCH_X86
>> > > #define BOOTEFI_NAME "BOOTIA32.EFI"
>> > > #endif
>> > > 
>> > > #if HOST_ARCH == HOST_ARCH_AARCH64
>> > > #define BOOTEFI_NAME "BOOTAA64.EFI"
>> > > #endif
>> > > 
>> > > #if HOST_ARCH == HOST_ARCH_ARM
>> > > #define BOOTEFI_NAME "BOOTARM.EFI"
>> > > #endif
>> > > 
>> > > #if HOST_ARCH == HOST_ARCH_RISCV32
>> > > #define BOOTEFI_NAME "BOOTRISCV32.EFI"
>> > > #endif
>> > > 
>> > > #if HOST_ARCH == HOST_ARCH_RISCV64
>> > > #define BOOTEFI_NAME "BOOTRISCV64.EFI"
>> > > #endif
>> > > 
>> > > #ifndef BOOTEFI_NAME
>> > > #error Unsupported UEFI architecture
>> > > #endif
>> > > 
>> > > #endif
>> > 
>> > Maybe sanbox is special, but using the host architecture for actual
>> > boards makes no sense.  I see this has made its way into master
>> > already, but when I cross-build for apple_m1_defconfig on an amd64
>> > machine I end up with:
>> > 
>> >     $ strings ./lib/efi_loader/efi_bootmgr.o | grep BOOT
>> >     /EFI/BOOT/BOOTX64.EFI
>> > 
>> > The original diff that used CONFIG_ARM64, CONFIG_ARM, etc, did this
>> > right.
>> 
>> Hmm, forget about that.  The problem is in the sed expression in the
>> toplevel Makefile that is used to MK_ARCH that ends up setting
>> HOST_ARCH incorrectly.  Using a variable named HOST_ARCH to hold the
>> target architecture doesn't help understanding what's going wrong here
>> of course...
>
>I can nod to Mark's comment here.
>Even though HOST_ARCH might work, it's quite confusing.
>Apparently it looks wrong as Mark said.
>
>Please address this comment properly as you modified my patch.
>
>What I basically recommend is:
>* In (top-dir)/Makefile
>  - s/HOST_ARCH/MK_ARCH/g
>  - add
>      if (CONFIG_SANDBOX)
>          HOST_ARCH = $(MK_ARCH)
>  - remove "undefine MK_ARCH"
>* In efi_default_filename.h
>  - s/HOST_ARCH/MK_ARCH/g
>
>This way, HOST_ARCH is only used in sandbox-related code.

TARGET_ARCH would be a better variable name.

Best regards

Heinrich

>
>-Takahiro Akashi
diff mbox series

Patch

diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
index c55023889c..6a3110f27b 100644
--- a/include/config_distro_bootcmd.h
+++ b/include/config_distro_bootcmd.h
@@ -91,19 +91,7 @@ 
 #endif
 
 #ifdef CONFIG_EFI_LOADER
-#if defined(CONFIG_ARM64)
-#define BOOTEFI_NAME "bootaa64.efi"
-#elif defined(CONFIG_ARM)
-#define BOOTEFI_NAME "bootarm.efi"
-#elif defined(CONFIG_X86_RUN_32BIT)
-#define BOOTEFI_NAME "bootia32.efi"
-#elif defined(CONFIG_X86_RUN_64BIT)
-#define BOOTEFI_NAME "bootx64.efi"
-#elif defined(CONFIG_ARCH_RV32I)
-#define BOOTEFI_NAME "bootriscv32.efi"
-#elif defined(CONFIG_ARCH_RV64I)
-#define BOOTEFI_NAME "bootriscv64.efi"
-#endif
+#include <efi_default_filename.h>
 #endif
 
 #ifdef BOOTEFI_NAME
diff --git a/include/efi_default_filename.h b/include/efi_default_filename.h
new file mode 100644
index 0000000000..cb2ef9e131
--- /dev/null
+++ b/include/efi_default_filename.h
@@ -0,0 +1,33 @@ 
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Default boot file name when none is present in the FilePath.
+ * This is defined in the UEFI specification.
+ *
+ * Copyright (c) 2022, Linaro Limited
+ */
+#ifndef _EFI_DEFAULT_FILENAME_H
+#define _EFI_DEFAULT_FILENAME_H
+
+#if defined(CONFIG_ARM64)
+#define BOOTEFI_NAME "BOOTAA64.EFI"
+#elif defined(CONFIG_ARM)
+#define BOOTEFI_NAME "BOOTARM.EFI"
+#elif defined(CONFIG_X86_64)
+#define BOOTEFI_NAME "BOOTX64.EFI"
+#elif defined(CONFIG_X86)
+#define BOOTEFI_NAME "BOOTIA32.EFI"
+#elif defined(CONFIG_ARCH_RV32I)
+#define BOOTEFI_NAME "BOOTRISCV32.EFI"
+#elif defined(CONFIG_ARCH_RV64I)
+#define BOOTEFI_NAME "BOOTRISCV64.EFI"
+#elif defined(CONFIG_SANDBOX)
+/*
+ * SANDBOX is not defined in UEFI specification, but
+ * this definition avoids build failure for SANDBOX.
+ */
+#define BOOTEFI_NAME "BOOTSANDBOX.EFI"
+#else
+#error Unsupported UEFI architecture
+#endif
+
+#endif
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
index 8c04ecbdc8..22a4302aac 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -11,6 +11,7 @@ 
 #include <charset.h>
 #include <log.h>
 #include <malloc.h>
+#include <efi_default_filename.h>
 #include <efi_loader.h>
 #include <efi_variable.h>
 #include <asm/unaligned.h>
@@ -30,6 +31,50 @@  static const struct efi_runtime_services *rs;
  * should do normal or recovery boot.
  */
 
+/**
+ * expand_media_path() - expand a device path for default file name
+ * @device_path:	device path to check against
+ *
+ * If @device_path is a media or disk partition which houses a file
+ * system, this function returns a full device path which contains
+ * an architecture-specific default file name for removable media.
+ *
+ * Return:	a newly allocated device path
+ */
+static
+struct efi_device_path *expand_media_path(struct efi_device_path *device_path)
+{
+	struct efi_device_path *dp, *full_path;
+	efi_handle_t handle;
+	efi_status_t ret;
+
+	if (!device_path)
+		return NULL;
+
+	/*
+	 * If device_path is a (removable) media or partition which provides
+	 * simple file system protocol, append a default file name to support
+	 * booting from removable media.
+	 */
+	dp = device_path;
+	ret = efi_locate_device_path(&efi_simple_file_system_protocol_guid,
+				     &dp, &handle);
+	if (ret == EFI_SUCCESS) {
+		if (dp->type == DEVICE_PATH_TYPE_END) {
+			dp = efi_dp_from_file(NULL, 0,
+					      "/EFI/BOOT/" BOOTEFI_NAME);
+			full_path = efi_dp_append(device_path, dp);
+			efi_free_pool(dp);
+		} else {
+			full_path = efi_dp_dup(device_path);
+		}
+	} else {
+		full_path = efi_dp_dup(device_path);
+	}
+
+	return full_path;
+}
+
 /**
  * try_load_entry() - try to load image for boot option
  *
@@ -68,13 +113,16 @@  static efi_status_t try_load_entry(u16 n, efi_handle_t *handle,
 	}
 
 	if (lo.attributes & LOAD_OPTION_ACTIVE) {
+		struct efi_device_path *file_path;
 		u32 attributes;
 
 		log_debug("%s: trying to load \"%ls\" from %pD\n",
 			  __func__, lo.label, lo.file_path);
 
-		ret = EFI_CALL(efi_load_image(true, efi_root, lo.file_path,
+		file_path = expand_media_path(lo.file_path);
+		ret = EFI_CALL(efi_load_image(true, efi_root, file_path,
 					      NULL, 0, handle));
+		efi_free_pool(file_path);
 		if (ret != EFI_SUCCESS) {
 			log_warning("Loading %ls '%ls' failed\n",
 				    varname, lo.label);