Page 1 of 1

OS as UEFI application

Posted: Fri Jun 26, 2020 7:47 pm
by Ethin
So, I have a question: right now my kernel is BIOS-only. I'd like to transition away from that and use UEFI. However, paging is tripping me up.
The Paging article uses assembly. Presume, then, that I wish to use the Setting up Paging article. Would everything in that article work the same under UEFI? I know that for memory allocation I'd need to use EFI_BOOT_SERVICES.AllocatePages() to set up the page directory somewhere in RAM. Will this memory allocation remain even after I call EFI_BOOT_SERVICES.ExitBootServices()? What else will I need to do if I choose to make my kernel an EFI application so it doesn't need a boot loader to run? And what will I need to keep in mind? And, finally, is this even advisable? (e.g.: I presume my kernel will need to be able to handle being executed by a loader like Grub, if that's even possible as an UEFI application.)
Edit: I'd like to note that I'd like to use identity paging (primarily because that's just easier to understand and work with).

Re: OS as UEFI application

Posted: Sat Jun 27, 2020 1:00 am
by iansjack
Ethin wrote:I'd like to note that I'd like to use identity paging (primarily because that's just easier to understand and work with).
So why are you using paging at all?

In what way do you think identity paging is easier to understand and work with than some useful form of paging?

Re: OS as UEFI application

Posted: Sat Jun 27, 2020 1:47 am
by nullplan
iansjack wrote:So why are you using paging at all?
My guess (coupled with the fact he's using UEFI) is that he wants to use Long Mode, which requires paging to be enabled.
Ethin wrote:I know that for memory allocation I'd need to use EFI_BOOT_SERVICES.AllocatePages() to set up the page directory somewhere in RAM. Will this memory allocation remain even after I call EFI_BOOT_SERVICES.ExitBootServices()?
Before you call ExitBootServices(), you can only use the memory allocated as above. After you call that service, you can use all memory you want that is marked as something usable in the UEFI memory map. Therefore, all the allocated pages will remain right where they are. You just can use all the other ones as well now.

Re: OS as UEFI application

Posted: Sat Jun 27, 2020 1:55 am
by Ethin
nullplan wrote:
iansjack wrote:So why are you using paging at all?
My guess (coupled with the fact he's using UEFI) is that he wants to use Long Mode, which requires paging to be enabled.
Ethin wrote:I know that for memory allocation I'd need to use EFI_BOOT_SERVICES.AllocatePages() to set up the page directory somewhere in RAM. Will this memory allocation remain even after I call EFI_BOOT_SERVICES.ExitBootServices()?
Before you call ExitBootServices(), you can only use the memory allocated as above. After you call that service, you can use all memory you want that is marked as something usable in the UEFI memory map. Therefore, all the allocated pages will remain right where they are. You just can use all the other ones as well now.
Thanks. And though I'm not using UEFI yet I'd like to transition to it, which is why I posted this topic. AndI'm in long mode too.

Re: OS as UEFI application

Posted: Sat Jun 27, 2020 12:25 pm
by Octocontrabass
Ethin wrote:The Paging article uses assembly. Presume, then, that I wish to use the Setting up Paging article. Would everything in that article work the same under UEFI?
Yes, but both of those articles are for plain 32-bit paging, which will not work in long mode. (And anyway, you can't load CR3 without using assembly.)
Ethin wrote:I know that for memory allocation I'd need to use EFI_BOOT_SERVICES.AllocatePages() to set up the page directory somewhere in RAM.
That's only necessary if you set up your page tables before calling ExitBootServices(). You can set up your page tables after the call to ExitBootServices() and then you don't need to worry about the firmware at all (unless you want to call runtime services).
Ethin wrote:Will this memory allocation remain even after I call EFI_BOOT_SERVICES.ExitBootServices()?
As long as you allocate them as type EfiLoaderData, yes.
Ethin wrote:What else will I need to do if I choose to make my kernel an EFI application so it doesn't need a boot loader to run?
You'll need to package your kernel as a PE binary, since UEFI doesn't support ELF. You may need to do some funky things to ensure you call UEFI services with the correct ABI, since they don't use the System V ABI.
Ethin wrote:And what will I need to keep in mind?
Firmware bugs exist and may cause trouble for you.
Ethin wrote:And, finally, is this even advisable?
I don't see anything wrong with it. I'd use a separate bootloader, but that's really more personal preference than anything technical (unless your kernel outgrows the EFI system partition, which is pretty unlikely).
Ethin wrote:(e.g.: I presume my kernel will need to be able to handle being executed by a loader like Grub, if that's even possible as an UEFI application.)
You won't have to handle anything special. It'll look the same as if the firmware loaded your kernel directly.
Ethin wrote:I'd like to note that I'd like to use identity paging (primarily because that's just easier to understand and work with).
What will you do about address space fragmentation?

Re: OS as UEFI application

Posted: Sat Jun 27, 2020 4:10 pm
by zaval
Ethin wrote: So, I have a question: right now my kernel is BIOS-only. I'd like to transition away from
that and use UEFI. However, paging is tripping me up.
The Paging article uses assembly. Presume, then,
that I wish to use the Setting up Paging
article. Would everything in that article work the same under UEFI? I know that for memory
allocation I'd need to use EFI_BOOT_SERVICES.AllocatePages() to set up the page directory
somewhere in RAM. Will this memory allocation remain even after I call
EFI_BOOT_SERVICES.ExitBootServices()?
Every address in the memory map you get from GetMemoryMap(), remains valid after
calling ExitBootServices(). But if you deploy new mapping, those pages, with allocated by you incl.
would be accessible only if they have valid entries in the mapping structures
you have built. ExitBootServices() transfers memory ownership to you and makes
all Boot Services and protocols unavailable. Runtime Sevices will be available only if
you preserved their original addresses in your mapping or conducted setting non-identity
mapped mapping for them correctly. it's described in the specification.
What else will I need to do if I choose to make my
kernel an EFI application so it doesn't need a boot loader to run? And what will I need to
keep in mind? And, finally, is this even advisable? (e.g.: I presume my kernel will need to
be able to handle being executed by a loader like Grub, if that's even possible as an UEFI
application.)
Edit: I'd like to note that I'd like to use identity paging (primarily because that's just
easier to understand and work with).
It's not how it was meant to be, which is pretty clear from reading the specification.
just like wearing underpants as a hat. it's not forbidden,
it's possible and you even will look original, but does it make it "only a matter of preference"?
ESP is meant to contain small executables, mostly loaders. kernels, normally reside in their
installation target - their own boot volume. organized the way, OS creators think is the best.
putting your kernel in ESP, limits you in a great deal of ways. also, your kernel cannot really
be a UEFI application, it only can pretend to be it at the short period of booting. once
it gets to its role of an OS, it cannot be a UEFI application.

identity mapping for OS is as bad as wrapping the OS into an OSL. don't be lazy/scared to
deploy a normal scheme from the beginning, otherwise you end up with lamery.