[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