I am new to the OSDev world and currently writing a 64-bit OS in rust. I split the project into a bootloader which uses the uefi-rs crate and the kernel. Based on online resources, I decided to make the kernel a higher half kernel. Unfortunately, I cannot load the kernel since the VMA in the linker script is the higher half address, which can't be accessed from the bootloader. If I understand correctly uefi provides identity mapping for the entire physical address space, therefore the higher half address (in my case: 0xFFFFFFFF80000000) is not mapped to a physical one. After some more research I found 2 ways around this problem:
1. setup custom paging in my bootloader and then map the virtual address.
2. add a section in the linker script that has a valid physical address and add an assembly stub that enables paging there, maps the higher half address and calls the kernel entry
I am currently struggling with the implementation but will try to work it out. Nevertheless, I still wonder why uefi-rs does not make a method for independently mapping memory available. Is this not possible?
Thanks in advance
[SOLVED] Calling 64-bit higher half kernel using uefi bootloader
[SOLVED] Calling 64-bit higher half kernel using uefi bootloader
Last edited by chicken on Wed Aug 14, 2024 2:23 am, edited 1 time in total.
Re: Calling 64-bit higher half kernel using uefi bootloader
I don't know much about UEFI, and I'm curious about point 2. Is there an address range in which UEFI guarantees physical memory will be present?
Kaph — a modular OS intended to be easy and fun to administer and code for.
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
Re: Calling 64-bit higher half kernel using uefi bootloader
It does not necessarily guarantee that any addresses will be available but rather inspects the memory map. Based on the highest available address in the map it then sets up paging with identity mapping up to that address.
For my second approach I would load a designated section in my kernel elf at the physical offset of 0x10000 (assuming that it is available - which it is based on testing). This section would contain an assembly snippet that sets up paging including the mapping of the higher half kernel offset. If everything checks out, I should be able to call the higher half entry address from there.
The approach is also described in the answer to this post: https://stackoverflow.com/questions/160 ... alf-kernel
For my second approach I would load a designated section in my kernel elf at the physical offset of 0x10000 (assuming that it is available - which it is based on testing). This section would contain an assembly snippet that sets up paging including the mapping of the higher half kernel offset. If everything checks out, I should be able to call the higher half entry address from there.
The approach is also described in the answer to this post: https://stackoverflow.com/questions/160 ... alf-kernel
Re: Calling 64-bit higher half kernel using uefi bootloader
The way I'm using is to have the 64-bit part be a regular ELF executable. The bootloader loads it at any page boundary in physical address space, then sets up the address space correctly for the ELF file. My kernel is linked to the -2GB line to take advantage of the kernel code model, but it also requires a linear mapping at the start of kernel space. Also, the bootloader needs to identity map the trampoline for jumping to the kernel itself.
The bootloader writes the arguments to the kernel into the initial boot stack for the kernel to find after taking control. Part of that is the address map, in which the bootloader has reserved the kernel image and the initial page tables (so it just added those addresses to the reserved address list). The kernel itself never needs to know its load address, and indeed doesn't even need to be contiguous in physical memory.
The bootloader writes the arguments to the kernel into the initial boot stack for the kernel to find after taking control. Part of that is the address map, in which the bootloader has reserved the kernel image and the initial page tables (so it just added those addresses to the reserved address list). The kernel itself never needs to know its load address, and indeed doesn't even need to be contiguous in physical memory.
Carpe diem!
-
- Member
- Posts: 5560
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Calling 64-bit higher half kernel using uefi bootloader
I ended up going with the first approach and it works as expected. Thanks