OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Sep 24, 2021 10:50 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: UEFI in assembler
PostPosted: Sun May 02, 2021 5:57 am 
Offline

Joined: Sat May 01, 2021 8:47 pm
Posts: 15
Where do I learn about UEFI (the spec is very complex), because the bare bones tutorials talk about the text mode buffer(very old), and I want to learn to UEFI in-depth, because tutorials tell you some offsets and little else.. I can only find crap tutorials


Top
 Profile  
 
 Post subject: Re: UEFI in assembler
PostPosted: Sun May 02, 2021 10:34 pm 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 1090
Well, which is it? Do you want to learn in depth or do you want a tutorial. We have a UEFI tutorial in the Wiki for you to peruse at your leisure, and if you want to go in-depth, there is the UEFI specification. It's not very complicated. UEFI works with PE DLLs (essentially; you have to make sure your code is position independent). Chapter 4 of the spec tells you what your entry point looks like and most of the remaining chapters are a reference for all the services you can call. But just like you don't need to have all of Ralf Brown's Interrupt List memorized when creating a legacy bootloader, you don't need to know all of the UEFI spec to write a UEFI bootloader.

Unsurprisingly, the job of a bootloader (to load a file into memory) largely remains the same, but with UEFI you no longer have to limit yourself to 512 bytes.

_________________
Thou hast outraged, not insulted me, sir; but for that I ask thee not to beware of Starbuck; thou wouldst but laugh; but let Ahab beware of Ahab; beware of thyself, old man.


Top
 Profile  
 
 Post subject: Re: UEFI in assembler
PostPosted: Sun May 02, 2021 11:06 pm 
Offline
Member
Member
User avatar

Joined: Fri Feb 17, 2017 4:01 pm
Posts: 601
Location: Ukraine, Bachmut
you just need to conform to the calling convention for the particular architecture, there is nothing special in interfacing your loader, written in assembly, with UEFI, that provides the C language specified interface. just like any other C and assembly interaction. if you want to learn deep UEFI, then the only way is studying its specification. And I second, it's absolutely not complex. especially shouldn't be for one, who wants to write in assembly. ;)

nullplan confused something, telling you need your code to be position independent, it absolutely doesn't, rather opposite - your loader is a PE image and it will be loaded at some base, maybe that, you specify, if it's free. You need your assembler to be able to generate PE images.

_________________
future big goal: ANT - NT-like OS for mips, arm and x86.
current smaller goal: efify - UEFI for a couple of boards (mips and arm).


Top
 Profile  
 
 Post subject: Re: UEFI in assembler
PostPosted: Mon May 03, 2021 5:40 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
newosdeveloper2021 wrote:
Where do I learn about UEFI (the spec is very complex), because the bare bones tutorials talk about the text mode buffer(very old), and I want to learn to UEFI in-depth, because tutorials tell you some offsets and little else.. I can only find crap tutorials
The easiest would be with fasm (it has very good macro capabilities to use ABI wrappers and can generate PE executable with configurable subsystem). You'll need a function that converts standard calls to UEFI ABI, and then use the UEFI spec to figure out the parameters to each calls.
Both can be found on the wiki, the macro "uefi_call_wrapper" provides the ABI wrapper, and there are examples on how to read sectors, set screen resolution etc.

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: UEFI in assembler
PostPosted: Mon May 03, 2021 7:03 am 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 972
What others have said so far is correct. But let me ask for the "why?".

Using UEFI from assembler has zero benefits over using it from C. You mention that you want to learn UEFI in-depth but calling it from assembly will mainly teach you how to fight calling conventions and PIC idiosyncrasies and not really what UEFI is about. My 2¢: if you want to learn it in-depth, learn how it use it in C.

_________________
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].


Top
 Profile  
 
 Post subject: Re: UEFI in assembler
PostPosted: Mon May 03, 2021 12:15 pm 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 1090
zaval wrote:
nullplan confused something, telling you need your code to be position independent, it absolutely doesn't, rather opposite - your loader is a PE image and it will be loaded at some base, maybe that, you specify, if it's free. You need your assembler to be able to generate PE images.
I was under the impression the image had to be position independent, or else the UEFI would refuse to load it. Besides, I don't know ahead of time what addresses will be free, and having a PIC PE image will allow the UEFI to relocate the image properly wherever is space.
Korona wrote:
What others have said so far is correct. But let me ask for the "why?".
Well, the wisdom of doing any osdev at all can be disputed, but yeah, seconded. https://www.youtube.com/watch?v=wJ81MZUlrDo
That said, only the title of the thread talks about assembler, and the actual question is silent on the subject.

_________________
Thou hast outraged, not insulted me, sir; but for that I ask thee not to beware of Starbuck; thou wouldst but laugh; but let Ahab beware of Ahab; beware of thyself, old man.


Top
 Profile  
 
 Post subject: Re: UEFI in assembler
PostPosted: Mon May 03, 2021 12:52 pm 
Offline
Member
Member

Joined: Mon Feb 02, 2015 7:11 pm
Posts: 712
newosdeveloper2021 wrote:
Where do I learn about UEFI (the spec is very complex), because the bare bones tutorials talk about the text mode buffer(very old), and I want to learn to UEFI in-depth, because tutorials tell you some offsets and little else.. I can only find crap tutorials

See https://mjg59.dreamwidth.org/18773.html?thread=1003605 as a starting point.

nullplan wrote:
I was under the impression the image had to be position independent, or else the UEFI would refuse to load it. Besides, I don't know ahead of time what addresses will be free, and having a PIC PE image will allow the UEFI to relocate the image properly wherever is space.

This is correct. The UEFI executable needs to be position independent. UEFI can relocate your code anywhere.

nullplan wrote:
That said, only the title of the thread talks about assembler, and the actual question is silent on the subject.

Very few people are masochist enough to write a UEFI bootloader in assembly. It is unlikely that many people will be willing to take the time to help with this.

_________________
https://github.com/kiznit/rainbow-os


Top
 Profile  
 
 Post subject: Re: UEFI in assembler
PostPosted: Mon May 03, 2021 1:32 pm 
Offline
Member
Member

Joined: Fri May 11, 2018 6:51 am
Posts: 213
Korona wrote:
What others have said so far is correct. But let me ask for the "why?".

Using UEFI from assembler has zero benefits over using it from C. You mention that you want to learn UEFI in-depth but calling it from assembly will mainly teach you how to fight calling conventions and PIC idiosyncrasies and not really what UEFI is about. My 2¢: if you want to learn it in-depth, learn how it use it in C.
I totally agree with that.

Also:
newosdeveloper2021 wrote:
Where do I learn about UEFI (the spec is very complex), because the bare bones tutorials talk about the text mode buffer(very old), and I want to learn to UEFI in-depth, because tutorials tell you some offsets and little else.. I can only find crap tutorials.

If you really wanna avoid "crappy" tutorials, then read the spec, seriously. But, don't be scared: you won't need to read the WHOLE spec. Just some parts of it. If you find it too difficult, maybe you need to learn more about the theory behind operating systems and bootloaders in general. Also, you need to have some understanding about how C code gets compiled and linked, along with calling conventions etc. To build a UEFI application knowing what's going on, without blindly copy-pasting stuff from tutorials, you need to have some amount of knowledge and experience.

Could you be more specific and explain what do you find super-hard to understand in the UEFI spec?

_________________
Tilck, a Tiny Linux-Compatible Kernel: https://github.com/vvaltchev/tilck


Top
 Profile  
 
 Post subject: Re: UEFI in assembler
PostPosted: Mon May 03, 2021 1:47 pm 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 2716
When I started with UEFI, the biggest problem was an environment that could create EFI files. I'm not on Linux, and I don't have M$ compilers, only OpenWatcom. However, I solved it by installing cygwin, both the 32-bit and the 64-bit version (on different computers) and downloaded GCC.

I actually was pondering to use assembly too, so I could avoid cygwin / Linux dependencies in my project. I eventually solved it by checking in the efi-executables into my SVN so I don't have to build them.


Top
 Profile  
 
 Post subject: Re: UEFI in assembler
PostPosted: Mon May 03, 2021 2:09 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 3356
nullplan wrote:
I was under the impression the image had to be position independent, or else the UEFI would refuse to load it.

EFI binaries are supposed to be relocatable, which is almost the same as position-independent. I don't think the UEFI spec says anything about what will happen if your binary isn't relocatable. (OVMF will load it anyway, which makes it difficult to tell if your linker options are correct.)


Top
 Profile  
 
 Post subject: Re: UEFI in assembler
PostPosted: Mon May 03, 2021 2:40 pm 
Offline
Member
Member
User avatar

Joined: Fri Feb 17, 2017 4:01 pm
Posts: 601
Location: Ukraine, Bachmut
kzinti wrote:
This is correct. The UEFI executable needs to be position independent. UEFI can relocate your code anywhere.

relocating means fixing absolute addresses used inside instructions and data (pointers). It is NOT PIC. PE is not PIC by the nature.
nullplan wrote:
I was under the impression the image had to be position independent, or else the UEFI would refuse to load it. Besides, I don't know ahead of time what addresses will be free, and having a PIC PE image will allow the UEFI to relocate the image properly wherever is space.

You don't have to know free addresses, your PE image uses some as a base, it may be even 0; then the FW, when loading the image, looks if it can place it at this address, if it can, then that's all, if not, it relocates the image, fixing (changing) all the references to the absolute addresses, both in code and data. That's why it's not PIC, because PIC means no references to absolute addresses at all, all references are relative, for example, to the program counter. Then putting an image somewhere else wouldn't require fixing anything, since for example a reference "load word into reg R from the memory, that is N bytes above program counter" remains the same. Position dependent then would be "load word into reg R from the memory at the address A0". That's exactly what PE uses. if the image has been put not at the preferred base, then A0 needs to be changed to A1, before the image starts execution. It applies both to exes and dlls. loaders are exes. dlls would be something that imports/exports from/to other images. unfortunately, UEFI doesn't make use this feature (for example exporting Boot Services/Runtime Services is an obvious case, but they decided to invent almost the same instead, resulting in an uglier code).

Quote:
EFI binaries are supposed to be relocatable, which is almost the same as position-independent. I don't think the UEFI spec says anything about what will happen if your binary isn't relocatable. (OVMF will load it anyway, which makes it difficult to tell if your linker options are correct.)

The only way to make a PE image non-relocatable is to strip relocation information. If you do this and the image really has a non empty .reloc section and the preferred base, the image has been linked to isn't available, the FW has zero chances to start it. Unless it includes instruction decoder and some euristic to guess if these data (in the data sections) are pointers or something else.

_________________
future big goal: ANT - NT-like OS for mips, arm and x86.
current smaller goal: efify - UEFI for a couple of boards (mips and arm).


Top
 Profile  
 
 Post subject: Re: UEFI in assembler
PostPosted: Mon May 03, 2021 7:05 pm 
Offline
Member
Member

Joined: Mon Feb 02, 2015 7:11 pm
Posts: 712
zaval wrote:
relocating means fixing absolute addresses used inside instructions and data (pointers). It is NOT PIC. PE is not PIC by the nature.

I understand the difference. You still need to compile your UEFI bootloader as PIC and link it as PIE. At least you do when using GCC. Do you have a different experience?

If I remove either -fpic or -pie, my bootloader stops working.

Every source I can find says that EFI needs position-independant code (i.e. -fpic). This appears to be the way you tell GCC to build a relocatable binary.

_________________
https://github.com/kiznit/rainbow-os


Top
 Profile  
 
 Post subject: Re: UEFI in assembler
PostPosted: Mon May 03, 2021 7:43 pm 
Offline
Member
Member
User avatar

Joined: Fri Feb 17, 2017 4:01 pm
Posts: 601
Location: Ukraine, Bachmut
kzinti wrote:
zaval wrote:
relocating means fixing absolute addresses used inside instructions and data (pointers). It is NOT PIC. PE is not PIC by the nature.

I understand the difference. You still need to compile your UEFI bootloader as PIC and link it as PIE. At least you do when using GCC. Do you have a different experience?

If I remove either -fpic or -pie, my bootloader stops working.

That's the weirdness of GCC (or even that gnu-efi cruft), that has nothing to do with either the PE image format or UEFI. I don't use GCC.

Quote:
Every source I can find says that EFI needs position-independant code (i.e. -fpic). This appears to be the way you tell GCC to build a relocatable binary.

for some incomprehensible reasons, this way, they produce an ELF shared object (that needs to be PIC) and wrap it into PE, instead of targetting PE directly... It's just, the right tool needs to be used, a normal PE generating compiler toolset, in this case. If you can't use MSVC, then Clang maybe? But anyway, that -fpic option for building an UEFI application is a useless artifact, forced on you by the strange attitude of gnu/folks. Still I believe, that mingw thing should be free of this nonsense (given gnu-efi is ditched as well, of course).

_________________
future big goal: ANT - NT-like OS for mips, arm and x86.
current smaller goal: efify - UEFI for a couple of boards (mips and arm).


Top
 Profile  
 
 Post subject: Re: UEFI in assembler
PostPosted: Mon May 03, 2021 8:04 pm 
Offline
Member
Member

Joined: Mon Feb 02, 2015 7:11 pm
Posts: 712
I have used mingw in the past and it is much easier to build an UEFI app with it (you don't need any of the gnu-efi trickeries).

That said, mingw actually forces fpic on you. It doesn't magically disappear. Here is what happens if you specify "-fpic" on the command line with mingw:

Code:
foo.c:1:0: warning: -fPIC ignored for target (all code is position independent) [enabled by default]

So yeah... If you use mingw, you are actually generating position-independent code.

You are also right that PE doesn't require it.

Ah the joys of computer programming.

_________________
https://github.com/kiznit/rainbow-os


Top
 Profile  
 
 Post subject: Re: UEFI in assembler
PostPosted: Mon May 03, 2021 10:27 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 3356
kzinti wrote:
So yeah... If you use mingw, you are actually generating position-independent code.

Despite the warning, GCC is generating the right code.

PE does require RIP-relative addressing if the executable might be loaded above 2GB. That's probably the reason why PIC is always enabled for 64-bit Windows targets.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 21 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group