Page 1 of 1

Paging in 32 bit to 64 bit bootstrap code

Posted: Sun Jul 14, 2024 8:44 pm
by glolichen
I'm wondering what regions to map in 32 bit long mode bootstrapping code. I'm thinking of mapping 0xFFFFFFFF80000000->0xFFFFFFFFFFFFFFFF (which is where the kernel is) to 0x0->0x7FFFFFFF and also identity mapping 0x0->0x7FFFFFFF. Please tell me if this is a good plan or if there's a better option.

Re: Paging in 32 bit to 64 bit bootstrap code

Posted: Mon Jul 15, 2024 8:34 am
by nullplan
Hi,

you should map everything the way your kernel needs it. I am building my kernel as a normal ELF file. The bootloader can then map all LOAD segments the way they need to be mapped. In order to solve the problem of accessing physical memory, I also map all of physical memory to 0xFFFF800000000000 (start of kernel space).

The CPU requires that when the switch happens, you identity map the boot GDT and the trampoline code (and highly likely also the boot stack). I could do that with bespoke mappings, but since I have the linear mapping, I can just do

Code: Select all

pml4[0] = pml4[256];
and thus identity map the whole first 2GB. The kernel can undo this assignment as soon as it has loaded its own stack, code, and GDT.

Re: Paging in 32 bit to 64 bit bootstrap code

Posted: Mon Jul 15, 2024 10:43 am
by Octocontrabass
glolichen wrote: Sun Jul 14, 2024 8:44 pmI'm thinking of mapping 0xFFFFFFFF80000000->0xFFFFFFFFFFFFFFFF (which is where the kernel is) to 0x0->0x7FFFFFFF
Fixed mappings work fine with legacy BIOS, but UEFI doesn't guarantee usable memory at specific addresses. You should generate the kernel mappings at runtime so you can load your kernel at any physical address.

Re: Paging in 32 bit to 64 bit bootstrap code

Posted: Fri Jul 19, 2024 7:43 pm
by glolichen
nullplan wrote: Mon Jul 15, 2024 8:34 am Hi,

you should map everything the way your kernel needs it. I am building my kernel as a normal ELF file. The bootloader can then map all LOAD segments the way they need to be mapped. In order to solve the problem of accessing physical memory, I also map all of physical memory to 0xFFFF800000000000 (start of kernel space).

The CPU requires that when the switch happens, you identity map the boot GDT and the trampoline code (and highly likely also the boot stack). I could do that with bespoke mappings, but since I have the linear mapping, I can just do

Code: Select all

pml4[0] = pml4[256];
and thus identity map the whole first 2GB. The kernel can undo this assignment as soon as it has loaded its own stack, code, and GDT.
Thanks for your help, I'll look into recursive mapping when I get to doing more memory management.