[GSoC] Ways to make the x86_64 port work with UEFI
Amaan Cheval
amaan.cheval at gmail.com
Fri May 25 17:10:59 UTC 2018
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!
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?
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
More information about the devel
mailing list