[U-Boot] [PATCH v2 00/18] efi_loader: enable EFI driver provided block device

Simon Glass sjg at chromium.org
Mon Jan 22 00:30:02 UTC 2018


Hi Heinrich,

On 19 January 2018 at 00:41, Heinrich Schuchardt <xypron.glpk at gmx.de> wrote:
> On 01/19/2018 12:00 AM, Simon Glass wrote:
>>
>> Hi Heinrich,
>>
>> On 17 January 2018 at 11:15, Heinrich Schuchardt <xypron.glpk at gmx.de>
>> wrote:
>>>
>>> With this patch series an EFI application or driver can supply
>>> a block device which in turn can be used to download an image.
>>>
>>> E.g. we can load iPXE, connect iSCSI drives, download grub from the
>>> SAN and afterwards with grub download and run an EFI application.
>>> Booting Linux from an iSCSI drive was successful on arm64.
>>>
>>> v2:
>>>          Add an additional patch to fix ExitBootServices.
>>>          Provide comments for EFI block driver.
>>>          Avoid printing when not in debug mode
>>>          Add product tools/file2include to .gitignore.
>>>          Put the patch with the test for block io after the patch for the
>>>          driver.
>>>
>>> Heinrich Schuchardt (18):
>>>    efi_loader: return NULL from device path functions
>>>    efi_loader: address of the simple file system protocol
>>>    efi_loader: correct find simple file system protocol
>>>    efi_loader: print device path when entering efi_load_image
>>>    efi_loader: allocate correct memory type for EFI image
>>>    efi_loader: check tables in helloworld.efi
>>>    efi_loader: fix StartImage bootservice
>>>    efi_loader: efi_disk_register: correctly determine if_type_name
>>>    efi_loader: make efi_block_io_guid a global symbol
>>>    efi_loader: provide a function to create a partition node
>>>    efi_loader: make efi_disk_create_partitions a global symbol
>>>    efi_loader: correct EFI_BLOCK_IO_PROTOCOL definitions
>>>    efi_loader: provide function to get last node of a device path
>>>    efi_loader: provide links between devices EFI handles
>>>    tools: provide a tool to convert a binary file to an include
>>>    efi_driver: EFI block driver
>>>    efi_selftest: provide a test for block io
>>>    efi_loader: fix ExitBootServices
>>>
>>>   MAINTAINERS                                  |   1 +
>>>   common/board_r.c                             |   3 +
>>>   drivers/block/blk-uclass.c                   |   4 +-
>>>   include/blk.h                                |   1 +
>>>   include/config_fallbacks.h                   |   1 +
>>>   include/dm/device.h                          |   4 +
>>>   include/dm/uclass-id.h                       |   1 +
>>>   include/efi_api.h                            |  16 +-
>>>   include/efi_driver.h                         |  30 ++
>>>   include/efi_loader.h                         |  21 +-
>>>   lib/Makefile                                 |   1 +
>>>   lib/efi_driver/Makefile                      |  13 +
>>>   lib/efi_driver/efi_block_device.c            | 175 ++++++++++++
>>>   lib/efi_driver/efi_uclass.c                  | 330
>>> ++++++++++++++++++++++
>>>   lib/efi_loader/efi_boottime.c                |  42 ++-
>>>   lib/efi_loader/efi_device_path.c             | 168 +++++++++---
>>>   lib/efi_loader/efi_disk.c                    | 137 +++++++---
>>>   lib/efi_loader/efi_image_loader.c            |  64 +++--
>>>   lib/efi_loader/helloworld.c                  |  26 ++
>>>   lib/efi_selftest/Makefile                    |   4 +
>>>   lib/efi_selftest/efi_selftest_block_device.c | 395
>>> +++++++++++++++++++++++++++
>>>   lib/efi_selftest/efi_selftest_disk_image.h   |  69 +++++
>>>   tools/.gitignore                             |   1 +
>>>   tools/Makefile                               |   3 +
>>>   tools/file2include.c                         | 106 +++++++
>>>   25 files changed, 1493 insertions(+), 123 deletions(-)
>>>   create mode 100644 include/efi_driver.h
>>>   create mode 100644 lib/efi_driver/Makefile
>>>   create mode 100644 lib/efi_driver/efi_block_device.c
>>>   create mode 100644 lib/efi_driver/efi_uclass.c
>>>   create mode 100644 lib/efi_selftest/efi_selftest_block_device.c
>>>   create mode 100644 lib/efi_selftest/efi_selftest_disk_image.h
>>>   create mode 100644 tools/file2include.c
>>>
>>> --
>>> 2.14.2
>>>
>>
>> Do you have a git tree with these patches? I get errors when applying
>> them.
>
>
> https://github.com/xypron2/u-boot.git
> branch efi-2018-03-rc1
>
>>
>> Some general comments for discussion, based on my limited understanding.
>>
>> At present from what I can tell, this looks through the UCLASS_EFI
>> drivers and instantiates a EFI driver/device for each. But it does not
>> seem to relate this to the U-Boot driver. It seems in fact to create a
>> new device. For example efi_bl_bind() calls blk_create_device().
>
>
> It is important to understand the sequence of events:
>
> U-Boot creates the EFI uclass.
> This uclass iterates over all EFI drivers (only one up to now).
> For each driver it creates a handle.
> on the handle it install the EFI_DRIVER_BINDING protocol.
> U-Boot loads iPXE.
> iPXE creates connects to a target on an iSCSI server
>
> Up to this point the iSCSI drive that we want to connect to as a block
> device is completely unknown to U-Boot.

This seems wonky to me. If U-Boot is hosting a device it should at
least know about it. We should not have a parallel system with its own
devices - it will get horribly confusing.

Is it not possible to create a device within the U-Boot driver model,
with an EFI device connecting to it?

>
> iPXE creates a handle for the target and installs the EFI_BLOCK_IO_PROTOCOL
> on the handle.
> iPXE calls ConnectController for this handle (which is referred to as
> controller).
> efi_connect_controller() loops over all handles implementing the
> EFI_DRIVER_BINDING protocol and calls the supported() method of the protocol
> to identify a driver supporting the controller.
> For each driver supporting the controller the start() method is called.
>
> The supported() and start() methods are implemented in the EFI uclass.
> In the supported() and start() methods the protocol GUID exposed by the EFI
> driver is compared to the GUIDS of the protocols installed on the controller
> to find a match.
> If a match is found the EFI uclass calls the bind function of the EFI
> driver.
>
> The EFI block driver now creates a block device.
> For the block device it creates partitions.
> On the partitions it installs the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.
> The EFI block driver has a read (efi_bl_read) and a write (efi_bl_write)
> function.
> These delegate reads and writes to the EFI_BLOCK_IO_PROTOCOL.
>
> Now iPXE tries to load grub.
> It calls the OpenVolume method of the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL of the
> partition to get an instance of the EFI_FILE_PROTOCOL.
> iPXE calls the Open method of the EFI_FILE_PROTOCOL with the path to grub.
> This method is implemented in efi_file_open().
> efi_file_open calls fs_exists() which calls ext4fs_exitsts() which calls the
> read method of the block device created by the EFI block driver. This method
> is implemented in efi_bl_read().
> efi_bl_read() calls the read_blocks() method of the EFI_BLOCK_IO_PROTOCOL
> exposed by iPXE.
> iPXE now uses the iSCSI protocol to read the requested blocks from the iSCSI
> server.

So are you saying that EFI discovers the device, and then creates a
block device within U-Boot? What is the parent of the block device?

>
>
>>
>> Instead I think there should be a real driver-rmodel device creasted
>> with UCLASS_EFI. It should be a child of the DM UCLASS_BLK device. The
>> could work in a similar way to now, except that it can scan DM devices
>> of a particular UCLASS rather than scanning DM drivers.
>>
>
> There is nothing to scan before the EFI application is running.
> The starting point is ConnectController being called by the EFI application
>
> The EFI uclass is not specific to block devices. It is responsible for all
> future EFI drivers. These could support any kind of virtual devices, e.g. a
> network interface.

Yes, I understand that.

But I think if EFI discovers a device, it should bind it in DM, then
attach an EFI device to that device if needed.

>
>> Also the patch that creates a tool to generate a binary as a header
>> file - can we use the same method as we use for other embedding? See
>> for example how .dtb is done.
>
>
> I avoid embedding a 64kiB disk image. My include results in 728 bytes in the
> binary. I really want compression here.
>
> With further patches I have to include binaries again which compress nicely.

Are you saying that you want to compress the disk image and compile it
into U-Boot? What does that have to do with the .dtb method? It should
not be hard to embedded a compressed image that way, too.

Regards,
Simon


More information about the U-Boot mailing list