Hacker News new | comments | ask | show | jobs | submit login
64-bit Tiano Core UEFI for the Raspberry Pi 3 (github.com)
67 points by Lwrless 9 months ago | hide | past | web | favorite | 24 comments

My understanding is that one of prerequisites of CoreOS is UEFI. The last time I checked there wasn't much support for CoreOS on Raspberry Pi, so I wonder if this might help.

Maybe. I'll look.

Is there much need for the big ass TianoCore? FreeBSD uses U-Boot's tiny implementation successfully, it even supports netbooting

Author here.

If you wanted to run you own drivers, or had code written specifically against protocols exported by Tiano components I believe the answer is - yes.

RaspberryPiPkg is the $35 64-bit Arm UEFI devkit.

Of couse the U-boot implementation of UEFI spec is getting better and better day by day, and that’s obviously awesome. I am sure someone will add ACPI support to it any day now. Having choice is good, and I wouldn’t want to live in a world with a single implementation. That said, Tiano (like it or not) /is/ the reference implementation, and you’re much less likely to run into surprises (today). Notice how I didn’t say Tiano is /better/, because in a number of ways (code quality, complexity, fragmentation) it’s pretty awful.

One thing the U-boot implementation excels at is embedded Arm board support - U-boot is the defacto firmware for most embedded hardware, and now all of that hardware is EFI-capable. Porting Tiano is effort you don’t want to spend.

That said, there are hybrid approaches - EFIDroid (efidroid.org) runs Tiano on top of LK, using LK’s platform support for drivers.

Not for regular purposes of booting Raspbian, or just a standard Linux kernel(+initramfs). In fact, even u-boot is not needed to boot Linux, because the RPi firmware is designed to boot Linux. FreeBSD uses u-boot because otherwise it'd have to implement Linux's conventions for booting, and it's just simpler to chainload via u-boot since u-boot already implements that.

RaspberriPiPkg can’t boot Raspbian today, since the latter is 32-bit. Can boot stock 64-bit SUSE and Ubuntu, though.

My point was, for booting Raspbian, this is not needed.

Booting Windows doesn't work with the U-Boot impl currently

That can be fixed.

And fixing this, is exactly what this 64-bit Tiano Core UEFI for the Raspberry Pi 3 is for. :-)

Yep, and being able to claim that U-boot can boot Windows (on x64 or Arm) would be a really strong statement around completeness. I hope someone gets to work on it soon (Alexander Graf ;-)?).

Oh, he is definitely trying. ;)

edk2.aarch is a 2 MB binary, which — while I'm sure it's bigger than uboot — isn't exactly big compared to any modern SD card.

I'd be interested to know what the memory footprint is like. I don't have an easy way to measure it.

If you run the “mmap” command in UEFI shell, and count the memory regions marked as Runtime Code and Runtime Data, that will give you the total resident (after booting OS) memory footprint.

Note that these numbers will also include Arm Trusted Firmware and firmware tables.

TianoCore was a horrible implementation of UEFI. When I used it to code against it had several standard-divergent parts.

Can you give details?

The specific problems I had I don't entirely remember (It was around 3 - 4 years ago at this point). The bug I encountered was relating to escaping the UEFI environment. My code was written to the UEFI 2.6 standards document, and it turns out that TianoCore diverged from that document with relation to how memory allocation was dealt with, and how setting up the post-boot environment was done.

EDIT: I think that it was something along the lines of some implementations (including TianoCore) required the ExitBootServices call to be performed more than once to exit the UEFI-controlled environment correctly? Even after doing that I had some problems with it.

There's a few problems there, but these amount to UEFI being a terrible, abominable spec.

The specification doesn't say that an implementation must not change the memory map inside ExitBootServices, and in practice many runtime drivers clean up or even perform RT Data allocations in that path. This results in the "MapKey is incorrect" error returned to the caller. (I've seen some that modify ACPI and SMBIOS on the fly inside the ExitBootServices path, awful, awful, awful).

So yes, the program calling ExitBootServices must be written to retry the call even if it really did avoid sandwiching any calls to UEFI between the last GetMemoryMap and ExitBootServices.

The other big Achille's heel of UEFI in general is the SetVirtualAddressMap() RT call and RT Services support in general, but Tiano's driver model makes it particularly easy to shoot yourself in the face and end up with an implementation that forces the OS to call RT services with identity mappings or even with mappings for supposedly non-RT regions. Ugh. MMIO is a favorite one to "forget" to add to the memory map as an RT entry.

UEFI uses the PE format for binaries, but doesn't actually mandate how PE should be used or what the allowed relocations are. You could build a PE binary that amounted to, say, tons of executable segments, each of which will be a separate memory map entry. Now since UEFI doesn't mandate exactly how an OS will assign virtual addresses (for SetVirtualAddressMap), nor exposes relative grouping of memory descriptors (forcing the OS to relocate these keeping relative distances) I can imagine a situation where RT drivers could break if the OS decided to aggressively compact the address map or instead introduce random large VA gaps between RT memory map entries.

> I think that it was something along the lines of some implementations (including TianoCore) required the ExitBootServices call to be performed more than once to exit the UEFI-controlled environment correctly?

As hinted at in andreiw's reply, this is entirely spec-compliant (if really annoying). Quoting from the spec:

"Firmware implementation may choose to do a partial shutdown of the boot services during the first call to ExitBootServices(). A UEFI OS loader should not make calls to any boot service function other than GetMemoryMap() after the first call to ExitBootServices()."

Ah, yes you're right, I remember reading that now. This means that I truly do not remember what the actual error was that caused me to give up.

A lot of it really is code quality issues, both in the core and some of the contributed I/O drivers.

Author here, feel free to AMA.

Can it netboot?

Not yet... the good news is that iPXE supports the SMSC USB NIC on the Pi. I don't know if iPXE will work out of the box, but I certainly intend on porting the iPXE NIC driver as a standalone (and GPL-licensed, of course) SNP implementation so you can use it with UEFI's own PXE implementation or anything else (like, shudder, it's shitty network tools...).

The biggest possible barrier to that today, which is still unknown, is the quality of the USB host controller. NICs use bulk, but there's no guarantee that the host controller driver is good enough. Time will tell, I suppose...

Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact