[U-Boot] [PATCH 00/14] EFI payload / application support v2

Alexander Graf
2016-01-31T21:43:45Z

On 01/31/2016 04:17 PM, Simon Glass wrote:
> Hi Alexander,
>
> On 14 January 2016 at 22:06, Alexander Graf <agraf@suse.de> wrote:
>> This is my Christmas present for my openSUSE friends :).
>>
>> U-Boot is a great project for embedded devices. However, convincing
>> everyone involved that only for "a few oddball ARM devices" we need to
>> support different configuration formats from grub2 when all other platforms
>> (PPC, System Z, x86) are standardized on a single format is a nightmare.
> Well some might argue that grub2 and UEFI are their own nightmares :-)

They are, but they are the same nightmare everyone else is dreaming ;).

>
>> So we started to explore alternatives. At first, people tried to get
>> grub2 running using the u-boot api interface. However, FWIW that one
>> doesn't support relocations, so you need to know where to link grub2 to
>> at compile time. It also seems to be broken more often than not. And on
>> top of it all, it's a one-off interface, so yet another thing to maintain.
> The API interface is mostly for closed-source work I think.
>
>> That led to a nifty idea. What if we can just implement the EFI application
>> protocol on top of U-Boot? Then we could compile a single grub2 binary for
>> uEFI based systems and U-Boot based systems and as soon as that one's loaded,
>> everything looks and feels (almost) the same.
>>
>> This patch set is the result of pursuing this endeavor.
>>
>> - I am successfully able to run grub2 and Linux EFI binaries with this code.
>> - When enabled, the resulting U-Boot binary only grows by ~10kb,
>> so it's very light weight.
>> - It works on 32bit ARM and AArch64.
>> - All storage devices are directly accessible
>> - No EFI variables
>> - Removable media booting (search for /efi/boot/boota{a64,arm}.efi)
>>
>> Of course, there are still a few things one could do on top:
>>
>> - Improve disk media detection (don't scan, use what information we have)
>> - Add EFI variable support using NVRAM
>> - Add GFX support
>> - Make EFI Shell work ;)
>> - Network device support
>> - Support for payload exit
>>
>> But so far, I'm very happy with the state of the patches. They completely
>> eliminate potential arguments against U-Boot internally and give users the
>> chance to run with the same level of comfort on all firmware types.
> I'd suggest creating a README with the above info. The cover letter
> will vanish pretty fast. Perhaps also update README.efi with this new
> option.

Good idea.

>
> Another thing you could list is efi_set_watchdog_timer().

What about it exactly? That it's not supported atm?

>
>> Version 2 was successfully tested to boot grub2 and Linux from there on a
>> HiKey (AArch64, dcache disabled) and on a BeagleBone Black.
> Do you have a UEFI image for BBB that I can put on an SD card or otherwise boot?

Phew, I hand-crafted one to play around with. You can use the hip04d01
image from

http://download.opensuse.org/repositories/devel:/ARM:/Factory:/Contrib:/HIP04D01/images/openSUSE-Tumbleweed-ARM-JeOS-hip04d01.armv7l.install.tar.xz

Just extract the tar.xz, to get to the actual image .xz file.

That image obviously has an incorrect kernel for the BBB, but everything
up to grub2 should work with it.

My plan was to slowly move all openSUSE arm targets that use our own
u-boot binaries to EFI once this patch set goes in ;).

> For now I've had a play with Minnowboard, which is x86. The main thing
> I noticed is that the API function implements should have EFIAPI on
> them also.

Yes :). I didn't expect anyone to actually care about running this on
x86 which is the only architecture that has different calling
conventions for EFI. I'm very pleasantly surprised that you are
interested and since you already have a patch to add them, I guess you
can as well just post that once the base support is in :).

> I'll make a few other comments on the patches. But overall
> it seems to function and I think your implementation is nice.

Thanks :)

>
> I was able to get grub to boot but it just says 'Welcome to GRUB!'
> and then 'error: disk ',gpt4' not found'. I'm not sure what that
> means.

It might mean memory corruption. I'm not sure where from though :). It
could also mean register clobbering.

>
>
> U-Boot 2016.01-00860-geb4b602-dirty (Jan 31 2016 - 08:02:54 -0700)
>
> CPU: x86_64, vendor Intel, device 30673h
> DRAM: 2 GiB
> efi_runtime_relocate: Relocating to offset=7ba5d000
> MMC: ValleyView SDHCI: 0, ValleyView SDHCI: 1
> SF: Detected W25Q64DW with page size 256 Bytes, erase size 4 KiB, total 8 MiB
> *** Warning - bad CRC, using default environment
>
> Video: 1280x1024x16
> Model: Intel Minnowboard Max
> SF: Detected W25Q64DW with page size 256 Bytes, erase size 4 KiB, total 8 MiB
> SCSI: SATA link 0 timeout.
> Target spinup took 0 ms.
> AHCI 0001.0300 32 slots 2 ports 3 Gbps 0x3 impl SATA mode
> flags: 64bit ncq stag pm led clo pio slum part sxs
> scanning bus for devices...
> Device 0: (1:0) Vendor: ATA Prod.: ADATA SP310 Rev: 5.2
> Type: Hard Disk
> Capacity: 30533.8 MB = 29.8 GB (62533296 x 512)
> Found 1 device(s).
> Net:
> Warning: eth_rtl8169 using MAC address from ROM
> eth0: eth_rtl8169
> Hit any key to stop autoboot: 0
> reading grubia32.efi
> 85504 bytes read in 16 ms (5.1 MiB/s)
> ## Starting EFI application at 0x00010000 ...
> WARNING: No device tree loaded, expect boot to fail
> Scanning disks on scsi...
> Scanning disks on usb...
> Scanning disks on mmc...
> Card did not respond to voltage select!
> MMC Device 2 not found
> MMC Device 3 not found
> Found 2 disks
> do_bootefi_exec:134 Jumping to 0x72857400
> EFI: Entry efi_open_protocol(7bab8c18, 728609a0, 7b857ab8, 7bab8c18,
> 00000000, 0x2)
> efi_open_protocol: Found protocol handler loaded_image0
> EFI: Exit 0
> EFI: Entry efi_locate_protocol(72860990, 00000000, 7b857ac8)
> EFI: Exit 0
> EFI: Entry efi_cin_get_mode(7baa79cc, 7b857af8, 00000000, 00000000)
> EFI: Exit 0
> EFI: Entry efi_locate_protocol(72860990, 00000000, 7b857aa8)
> EFI: Exit 0
> EFI: Entry efi_cin_get_mode(7baa79cc, 7b857ad8, 00000000, 00000000)
> EFI: Exit 0
> EFI: Entry efi_cout_enable_cursor(7baa79d8, 1)
> EFI: Exit 80000003
> EFI: Entry efi_allocate_pages(1, 2, 0x6, 7b857a74)
> EFI: Exit 0
> EFI: Entry efi_get_memory_map(7b857b04, 7286c000, 7b857a64, 7b857b08, 7b857a68)
> EFI: Exit 0
> EFI: Entry efi_allocate_pages(2, 2, 0x1ca15, 7b857a74)
> EFI: Exit 0
> EFI: Entry efi_free_pages(7286c000, 0x6)
> EFI: Exit 0
> EFI: Entry efi_set_watchdog_timer(0, 0x0, 0, 00000000)
> EFI: App called into unimplemented function efi_set_watchdog_timer
> EFI: Exit 80000003
> EFI: Exit 80000003
> EFI: App called into unimplemented function efi_set_watchdog_timer
> EFI: Exit 80000003
> EFI: Entry efi_locate_handle(2, 72860980, 00000000, 7b857a88, 72856fe0)
> EFI: Exit 0
> EFI: Entry efi_open_protocol(7b863108, 728609b0, 7b857a78, 7bab8c18,
> 00000000, 0x2)
> efi_open_protocol: Found protocol handler open_dp
> efi_disk_open_dp
> EFI: Exit 0
> EFI: Entry efi_open_protocol(7b863108, 72860980, 7b857a98, 7bab8c18,
> 00000000, 0x2)
> efi_open_protocol: Found protocol handler open_block
> efi_disk_open_block
> EFI: Exit 0
> EFI: Entry efi_open_protocol(7b8631d8, 728609b0, 7b857a78, 7bab8c18,
> 00000000, 0x2)
> efi_open_protocol: Found protocol handler open_dp
> efi_disk_open_dp
> EFI: Exit 0
> EFI: Entry efi_open_protocol(7b8631d8, 72860980, 7b857a98, 7bab8c18,
> 00000000, 0x2)
> efi_open_protocol: Found protocol handler open_block
> efi_disk_open_block
> EFI: Exit 0
> EFI: Entry efi_cout_set_attribute(7baa79d8, 70)
> EFI: Exit 80000003
> Welcome to GRUB!
>
> EFI: Entry efi_cout_set_attribute(7baa79d8, 7)
> EFI: Exit 80000003
> EFI: Entry efi_open_protocol(7bab8c18, 728609a0, 7b857ad8, 7bab8c18,
> 00000000, 0x2)
> efi_open_protocol: Found protocol handler loaded_image0
> EFI: Exit 0
> EFI: Entry efi_open_protocol(7bab8bd0, 728609b0, 7b857a78, 7bab8c18,
> 00000000, 0x2)
> efi_open_protocol: Found protocol handler bootefi0
> EFI: Exit 0
> error: disk `,gpt4' not found.
> Entering rescue mode...
> grub rescue>

Does grub see the hard disks? What happens when you do ls (hd,<TAB>?
Also, try the ls command but first do set debug=all to get grub internal
debugging enabled too.

>
>
> I suppose my grub could be wrong. If you can point me to one that I
> should use I could try again. I pushed your tree (rebased to mainline)
> plus my messing-around patch to u-boot-x86/efi-working.
>
> It would be good to get this series applied soon.

Awesome.

I'm currently rewriting the memory map code, making it more robust, easy
to understand and extensible for modules that may want to register
runtime service mmio regions.

Once that works and I have all of Leif's comments sorted out, I'll post v3.

Alex