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

Joel Sherrill joel at rtems.org
Fri May 25 17:21:09 UTC 2018


On Fri, May 25, 2018, 12:11 PM Amaan Cheval <amaan.cheval at gmail.com> wrote:

> Hey! Could you link me to some code that you used for the Deos setup
> you mentioned?
> My understanding is that the -shared option can link static archives
> to create a "shared" library in the sense that it doesn't include the
> usual crt0 runtime environment and whatnot, but the code within is
> still position-dependent. Given that the PE image that EFI needs is
> one that needs to be truly relocatable, this may not work - BUT, I've
> only just noticed the ./gnuefi/reloc_x86_64.c file which seems to
> handle some kinds of runtime relocations encoded within the converted
> PE file, so maybe this will work after all. I'll continue to
> investigate and let you know how it goes!
>

Deos isn't a good example except that you can compile with -fPIC and put
that code into a static library. Deos is a closed source Level A (man rated
flight) ARINC 653 RTOS. It's boot process reads configuration information
about each partition and associates .so's with each address space per the
configuration. It can't change after that.

The RTEMS exe is mostly linked as normal except to use some arguments to
say some symbols are from a shared library.

The base address of the exe is that of the provided virtual address space
with .data and .bss in their respective spaces.

And our entry point is in C so there is no asm before that. Great
simplification.


> Regarding how TLS differs with PIC - could you elaborate? Is it
> something we'll need to solve for if we go with the -fPIC option, or
> is it something we need to keep in mind as a limitation, but isn't
> really a blocker?
>

I don't think PIC changes the TLS mechanism on arm or PowerPC but on i386,
when not PIC the TLS base is in %gs and it's a subroutine call when PIC.
Just as well for Deos since they assume an application won't change the
segment register values.

Other than this one TLS difference, it is a normal exe to me. They just
magically provide their .so's before we run.

>
> On Fri, May 25, 2018 at 10:13 PM, Joel Sherrill <joel at rtems.org> wrote:
> >
> >
> > On Fri, May 25, 2018, 11:15 AM Amaan Cheval <amaan.cheval at gmail.com>
> wrote:
> >>
> >> Hey!
> >>
> >> 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
> >> load_elf.c[3])
> >>   - The loadfile function parses the program and section headers of
> >> the ELF file (through more function detours that are not really
> >> important)
> >>   - 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.
> >
> >
> > I'm using PIC on the Deos BSP. RTEMS is still a .a and exes are linked
> with
> > our static libraries and Deos .so.
> >
> > Unless the loader forces something, you can use PIC with no build system
> > changes.
> >
> > note that thread local storage is different on i386 with and without PIC.
> >>
> >>
> >> - 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
> >> mode).
> >>
> >> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20180525/ae2549ea/attachment-0002.html>


More information about the devel mailing list