[GSoC] Ways to make the x86_64 port work with UEFI

Amaan Cheval amaan.cheval at gmail.com
Fri May 25 16:15:33 UTC 2018


Skippable details about how FreeBSD handles the UEFI boot process!

Having looked into it a bit more, my understanding of how FreeBSD
handles this process is:
- They build a two-stage bootloader for EFI, called boot1.efi and loader.efi[1]
- loader.efi is an interactive prompt which may autoboot, or a "boot
kernelImg" command can be used to load the actual kernel
- The kernel is loaded as an ELF through helper functions. The
command_boot[2] function drives this:
  - In brief, through calls go through:
    command_boot -> mod_loadkld -> file_load ->
file_formats[i]->l_load (actually the loadfile function in
  - The loadfile function parses the program and section headers of
the ELF file (through more function detours that are not really
  - Once the ELF has been loaded at the correct entry_addr that it
expects to be loaded at in memory, the l_exec[4] function is called,
which is actually elf64_exec in elf64_freebsd.c[5], at which hopefully
through trampolining magic, the control flow will transfer to the
kernel or ELF module


What this means for RTEMS if we go with gnu-efi is essentially 2
options, given that the objcopy method of converting from ELF->PE
requires the ELF to be a position-independent shared library:

- Using -fPIC to compile all of RTEMS, including the RTEMS user's
application code. This way we'd have librtemsbso.so, librtemscpu.so,
etc. which would then be linked into user_app.c through -fPIC and
-shared flags still, creating one singular hello.so, which can then
finally be converted into hello.efi and put on a FAT filesystem and
booted. This seems doable, but I'm fairly concerned about it further
complicating our build system and likely being quite singular in its
focus on EFI.

- The FreeBSD way of a (loader.efi) and a hello.exe (ELF64) put on
possibly the same partition on the FAT filesystem required for UEFI
application images anyway. The loader.efi can find the hello.exe file
through perhaps a config file it can read or by having a magic-name
like rtems.exe or something. This effectively means we need an ELF
dynamic linker / loader (akin to ld.so) within RTEMS' source. I think
using FreeBSD's code for this should be fine. One added benefit of
this method is that librtems* and user applications remain as ELF64s,
which in the future could also be used with Multiboot with a slightly
modified "loader" (i.e. one which generates the apt Multiboot magic
header, and boots the PC from 32-bit protected mode to 64-bit long

I prefer the latter approach personally. If both of these seem too
complicated, we can of course go back to considering generating the PE
header format in ASM the way Linux distros use EFISTUB and the code
Chris shared (as I mentioned in my original blog post) for wimboot.
Those approaches may be significantly simpler in a sense, but may
limit how we use UEFI Services - I'm not sure about the details of
this yet - I can investigate if y'all aren't fond of the option I laid
down above.

Let me know!

[1] https://www.freebsd.org/cgi/man.cgi?query=loader&apropos=0&sektion=8&manpath=FreeBSD+11.1-RELEASE+and+Ports&arch=default&format=html
[2] https://github.com/freebsd/freebsd/blob/433bd38e3a0349f9f89f9d54594172c75b002b74/stand/common/boot.c#L53
[3] https://github.com/freebsd/freebsd/blob/d8596f6f687a64b994b065f3058155405dfc39db/stand/common/load_elf.c#L150
[4] https://github.com/freebsd/freebsd/blob/433bd38e3a0349f9f89f9d54594172c75b002b74/stand/common/boot.c#L107
[5] https://github.com/freebsd/freebsd/blob/d8596f6f687a64b994b065f3058155405dfc39db/stand/efi/loader/arch/amd64/elf64_freebsd.c#L93

On Sun, May 20, 2018 at 10:52 PM, Joel Sherrill <joel at rtems.org> wrote:
> On Sun, May 20, 2018, 12:10 PM Amaan Cheval <amaan.cheval at gmail.com> wrote:
>> On Sat, May 19, 2018 at 6:51 PM, Gedare Bloom <gedare at rtems.org> wrote:
>> > On Fri, May 18, 2018 at 5:53 PM, Joel Sherrill <joel at rtems.org> wrote:
>> >>
>> >>
>> >> On Fri, May 18, 2018 at 3:24 PM, Amaan Cheval <amaan.cheval at gmail.com>
>> >> wrote:
>> >>>
>> >>> Hi everyone!
>> >>>
>> >>> I've written a quick blog post summarizing the options I've considered
>> >>> to make the x86_64 port work with UEFI firmware - the primary winner
>> >>> seems to be in my eyes to use "gnu-efi" and to add support for the
>> >>> target "pei-x86-64" (aliased to "efi-app-x86_64") to
>> >>> "x86_64-rtems5-objcopy" in binutils. I've submitted a patch for this
>> >>> here[1].
>> >>
>> >>
>> >> That patch is quite simple so shouldn't be a problem if this is the
>> >> direction
>> >> that gets consensus.
>> >>>
>> >>>
>> >>> The blog post is here:
>> >>> https://blog.whatthedude.com/post/uefi-app-options/
>> >>>
>> >>> I'd appreciate all feedback (and please do let me know if I haven't
>> >>> provided enough context)!
>> >>>
>> >>> Specifically, some concerns I'd like to discuss are:
>> >>>
>> >>> - Does everyone agree with me on choosing gnu-efi + objcopy as our
>> >>> method of choice?
>> >>
>> >>
>> >> Does using gnu-efi add code that runs on the target? Can you point
>> >> us to the files, if so.
>> Sure. The files would run on the target, yes. These are the ones
>> listed here (as linked to in my blog post, perhaps without sufficient
>> emphasis):
>> https://wiki.osdev.org/UEFI#Developing_with_GNU-EFI
>> >>
>> >> Can you tell which approach FreeBSD takes?
>> FreeBSD takes the gnu-efi approach I see as the "winner" here (also a
>> link in the post):
>> https://github.com/freebsd/freebsd/blob/996b0b6d81cf31cd8d58af5d8b45f0b4945d960d/stand/efi/loader/Makefile#L98-L1
> This is (no surprise) appropriately licensed and IMO the winning solution.
> Knowing it is what FreeBSD does makes it an easy choice.
> A comment in the readme mentions there is a i386 version of this code so
> that could be used to let pc386 boot from UEFI.
>> >>
>> >>>
>> >>> - How do we integrate gnu-efi into our build process? A part of the
>> >>> RSB, making sure the path to the libraries are in an exported
>> >>> variable? Or perhaps a part of the RTEMS kernel itself if the licenses
>> >>> are compatible (I don't see any on the project[2], only copyright
>> >>> notices within the source files of the release versions).
>> >>
>> >>
>> >> GNU-efi would be built like qemu or the device tree compiler would
>> >> be my guess and x86_64-rtems toolset might add that to the standard
>> >> set of tools. License on host tools being GPL isn't an issue.
>> >>
>> >
>> > It appears to be a standard 2-clause BSD released by Intel as
>> > specified in the README file of gnu-efi.
>> >
>> >>
>> >>>
>> >>> - Regardless of how we manage UEFI, do we require Multiboot support
>> >>> too? Multiboot drops us in a 32-bit protected mode environment,
>> >>> whereas 64-bit UEFI firmware will boot us into 64-bit long mode - this
>> >>> would mean the kernel would need to support separate code-paths for
>> >>> the 2 if we want to support both methods.
>> >>
>> >>
>> >> That's a good question. For GSoC, I think UEFI is fine and perhaps a
>> >> ticket
>> >> under the general "modern PC support" ticket for multiboot support.
>> >> Unless
>> >> that eliminates a LOT of PCs.
>> >>
>> >> I don't want you to spend all summer getting an image to boot both
>> >> ways. Personally, I want you to have a working BSP one way. :)
>> > +1
>> >
>> Noted, thanks!
>> >>>
>> >>>
>> >>> [1] https://www.sourceware.org/ml/binutils/2018-05/msg00197.html
>> >>> [2] https://sourceforge.net/projects/gnu-efi/
>> >>
>> >>
>> >> --joel
>> >>
>> >> _______________________________________________
>> >> devel mailing list
>> >> devel at rtems.org
>> >> http://lists.rtems.org/mailman/listinfo/devel

More information about the devel mailing list