[SOLVED] Setting up Paging in the Bootloader (UEFI)

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Post Reply
chicken
Posts: 12
Joined: Fri Aug 09, 2024 4:30 am

[SOLVED] Setting up Paging in the Bootloader (UEFI)

Post by chicken »

I am writing a hobby OS with it's own uefi-target x64 bootloader. In the UEFI specification it states that identity-mapped paging is enabled:
Paging mode is enabled and any memory space defined by the UEFI memory map is identity mapped (virtual address equals physical address), although the attributes of certain regions may not have all read, write, and execute attributes or be unmarked for purposes of platform protection. The mappings to other regions, such as those for unaccepted memory, are undefined and may vary from implementation to implementation.
https://uefi.org/specs/UEFI/2.10/02_Ove ... -platforms

The kernel I am writing is supposed to be a higher-half kernel, thus I set up a new paging scheme in the loader that maps the kernel code pages, bootinformation, ... to higher half adddresses. But from what I know paging is usually set up in the kernel.

Are there any downsides to only setting it up in the loader?
Last edited by chicken on Fri Jan 03, 2025 2:43 pm, edited 1 time in total.
nullplan
Member
Member
Posts: 1819
Joined: Wed Aug 30, 2017 8:24 am

Re: Setting up Paging in the Bootloader (UEFI)

Post by nullplan »

Honestly, doing it in the bootloader (or a separate binary in general) is probably the cleanest solution.

The memory mappings are part of the operating environment of the code. When you write

Code: Select all

debug_print("Setting up kernel map\n");
the compiler and linker will turn this into something sensible only for the environment they know. The compiler will make assumptions such as "all strings can just go to the .rodata section", and those assumptions may be wrong if you have special needs, such as putting all strings needed before paging into a special section.

The setup I have sometimes seen is one where the pre-paging code is put into special sections that are then linked to the 1MB line, whereas all other code is linked to the 3GB or -2GB line. And this can work, if you ensure no cross-references, but it is far easier to do that when the pre-paging code and the paging code are in different binaries. This also ensures you can share code just by linking it in twice (the pre-paging code can be freed after the jump to higher half after all, so the additional memory is no big deal).

So I would always suggest putting the paging setup code into a separate binary, and in case of UEFI, you need a bootloader written for your own OS anyway. I also have my kernel be an ELF file. It is essentially a normal static executable, save for the fact that it has a load address of -2GB. This also solves the problem of figuring out which parts to map where, as I have normal program headers that do that.
Carpe diem!
Post Reply