[solved] Help needed to setup for kernel paging in uefi bootloader

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
ivinexo
Posts: 2
Joined: Sat Sep 13, 2025 2:13 am

[solved] Help needed to setup for kernel paging in uefi bootloader

Post by ivinexo »

Hello fine people!
I need help with setting up paging for my higher half os from my uefi bootloader, the problem is tho, that when i try to swich cr3 to my tabeles it causes a triple fault and resets.
I am trying rn to idenity map the entire memory so i know that the error isnt wrong remaping, and the kernel is compiled with PIC so it shouldnt be a problem.
ut it still resets after switching and i have no idea why even after a few days.
If you find an error in my code please help me!
Thenk you in advance :3

Here is the code for remaping phys to virt

Code: Select all

EFI_STATUS MMap(EFI_PHYSICAL_ADDRESS PHYS, EFI_VIRTUAL_ADDRESS VIRT,
                BOOLEAN Cached, UINT64 *PML4, EFI_SYSTEM_TABLE *SystemTable) {
  EFI_STATUS status;
  EFI_PHYSICAL_ADDRESS phys;
  UINTN EntryPML4 = VIRT >> 39 & 0x1ff;
  UINTN EntryPDPT = VIRT >> 30 & 0x1ff;
  UINTN EntryPD = VIRT >> 21 & 0x1ff;
  UINTN EnrtyPT = VIRT >> 12 & 0x1ff;

  // Find / make PML4 entry
  UINT64 *PDPT;
  if ((PML4[EntryPML4] & 1) == 0) {
    phys = 0;
    status = uefi_call_wrapper(SystemTable->BootServices->AllocatePages, 4,
                               AllocateAnyPages, EfiLoaderData, 1, &phys);
    if (status != EFI_SUCCESS) {
      Print(L"Failed to allocate memory for PDPT: %s\n",
            EFIStatusToStr(status));
      return status;
    }
    PDPT = (UINT64 *)phys;
    for (UINTN i = 0; i < 0x400; i++) {
      PDPT[i] = 0;
    }
    PML4[EntryPML4] = (UINT64)PDPT | 0x7;
  }

  PDPT = (UINT64 *)(PML4[EntryPML4] & ~0x7);

  // Find / make PDPT entry
  UINT64 *PD;
  if ((PDPT[EntryPDPT] & 1) == 0) {
    phys = 0;
    status = uefi_call_wrapper(SystemTable->BootServices->AllocatePages, 4,
                               AllocateAnyPages, EfiLoaderData, 1, &phys);
    if (status != EFI_SUCCESS) {
      Print(L"Failed to allocate memory for PD: %s\n", EFIStatusToStr(status));
      return status;
    }
    PD = (UINT64 *)phys;
    for (UINTN i = 0; i < 0x400; i++) {
      PD[i] = 0;
    }
    PDPT[EntryPDPT] = (UINT64)PD | 0x7 | (Cached ? (1 << 4) : 0);
  }

  PD = (UINT64 *)(PDPT[EntryPDPT] & ~0x7);

  // Find/make PD entry
  UINT64 *PT;
  if ((PD[EntryPD] & 1) == 0) {
    phys = 0;
    status = uefi_call_wrapper(SystemTable->BootServices->AllocatePages, 4,
                               AllocateAnyPages, EfiLoaderData, 1, &phys);
    if (status != EFI_SUCCESS) {
      Print(L"Failed to allocate memory for PT: %s\n", EFIStatusToStr(status));
      return status;
    }
    PT = (UINT64 *)phys;
    for (UINTN i = 0; i < 0x400; i++) {
      PT[i] = 0;
    }
    PD[EntryPD] = (UINT64)PT | 0x7;
  }
  PT = (UINT64 *)(PD[EntryPD] & ~0x7);

  // Make PT entry
  PT[EnrtyPT] = PHYS | 0x7;
  return EFI_SUCCESS;
}
and here is the code for idenity mapping

Code: Select all

  // Init page map
  EFI_PHYSICAL_ADDRESS phys = 0;
  UINT64 *PML4 = NULL;
  status = uefi_call_wrapper(SystemTable->BootServices->AllocatePages, 4,
                             AllocateAnyPages, EfiLoaderData, 1, &phys);
  if (status != EFI_SUCCESS) {
    Print(L"Failed to allocate memory for PML4: %s\n", EFIStatusToStr(status));
  }
  PML4 = (UINT64 *)phys;
  for (UINTN i = 0; i < 0x400; i++) {
    PML4[i] = 0;
  }

  // Identity map memory
  MEMORY_MAP_DESCRIPTOR *InitMemoryMapDesc = GetMemoryMap(SystemTable);
  EFI_PHYSICAL_ADDRESS MaxPhysAddress = 0x8000000;
  for (UINTN i = 0; i < InitMemoryMapDesc->MemoryMapSize;
       i += InitMemoryMapDesc->DescriptorSize) {
    EFI_MEMORY_DESCRIPTOR *Entry =
        (EFI_MEMORY_DESCRIPTOR *)(InitMemoryMapDesc->MemoryMap + i);
    MMap(Entry->PhysicalStart, Entry->PhysicalStart, Entry->Attribute & 0x1,
         PML4, SystemTable);
  }
and here is the code for getting memory map:

Code: Select all

MEMORY_MAP_DESCRIPTOR *GetMemoryMap(EFI_SYSTEM_TABLE *SystemTable) {
  EFI_STATUS status;
  MEMORY_MAP_DESCRIPTOR *MemoryMapDescriptor = NULL;
  status = uefi_call_wrapper(SystemTable->BootServices->AllocatePool, 3,
                             EfiLoaderData, sizeof(MEMORY_MAP_DESCRIPTOR),
                             &MemoryMapDescriptor);
  if (status != EFI_SUCCESS) {
    Print(L"Failed to allocate pool for MEMORY_MAP_DESCRIPTOR: %s\n",
          EFIStatusToStr(status));
    return NULL;
  }

  MemoryMapDescriptor->MemoryMapSize = 0;

  status = uefi_call_wrapper(
      SystemTable->BootServices->GetMemoryMap, 5,
      &(MemoryMapDescriptor->MemoryMapSize), MemoryMapDescriptor->MemoryMap,
      &(MemoryMapDescriptor->MapKey), &(MemoryMapDescriptor->DescriptorSize),
      &(MemoryMapDescriptor->DescriptorVersion));
  if (status != EFI_BUFFER_TOO_SMALL) {
    Print(L"Failed to get size of memory map: %s\n", EFIStatusToStr(status));
    return NULL;
  }

  MemoryMapDescriptor->MemoryMapSize += 5 * MemoryMapDescriptor->DescriptorSize;
  status = uefi_call_wrapper(SystemTable->BootServices->AllocatePool, 3,
                             EfiLoaderData, MemoryMapDescriptor->MemoryMapSize,
                             &(MemoryMapDescriptor->MemoryMap));
  if (status != EFI_SUCCESS) {
    Print(L"Failed to allocate memory for memory map: %s\n",
          EFIStatusToStr(status));
    return NULL;
  }

  status = uefi_call_wrapper(
      SystemTable->BootServices->GetMemoryMap, 5,
      &(MemoryMapDescriptor->MemoryMapSize), MemoryMapDescriptor->MemoryMap,
      &(MemoryMapDescriptor->MapKey), &(MemoryMapDescriptor->DescriptorSize),
      &(MemoryMapDescriptor->DescriptorVersion));
  if (status != EFI_SUCCESS) {
    Print(L"Failed to get memory map: %s\n", EFIStatusToStr(status));
    return NULL;
  }

  return MemoryMapDescriptor;
}
Last edited by ivinexo on Fri Feb 20, 2026 3:28 pm, edited 1 time in total.
Octocontrabass
Member
Member
Posts: 6245
Joined: Mon Mar 25, 2013 7:01 pm

Re: Help needed to setup for kernel paging in uefi bootloader

Post by Octocontrabass »

ivinexo wrote: Fri Feb 20, 2026 4:34 amwhen i try to swich cr3 to my tabeles it causes a triple fault and resets.
What does your virtual machine say about the cause of the triple fault? (For example, if you're using QEMU, add "-d int" to the command line to get a log of the exceptions leading up to the triple fault.)
ivinexo
Posts: 2
Joined: Sat Sep 13, 2025 2:13 am

Re: Help needed to setup for kernel paging in uefi bootloader

Post by ivinexo »

Thanks! I didnt know qemu could do that! …but in from the time i submitted the post to the time it got approved i didnt something that made the code work… i have no idea what it was but it works now… so i guess its solved? Thanks anyway!
Post Reply