From 36c273ea13f0d341cb3fcdb16d7eb094e81c2430 Mon Sep 17 00:00:00 2001 From: Aiken Harris Date: Mon, 15 Dec 2025 13:24:02 +0100 Subject: [PATCH] Implement early page table mapping routines --- xtoskrnl/CMakeLists.txt | 1 + xtoskrnl/includes/mm.hh | 1 + xtoskrnl/includes/mm/pte.hh | 39 ++++++ xtoskrnl/mm/pte.cc | 245 ++++++++++++++++++++++++++++++++++++ 4 files changed, 286 insertions(+) create mode 100644 xtoskrnl/includes/mm/pte.hh create mode 100644 xtoskrnl/mm/pte.cc diff --git a/xtoskrnl/CMakeLists.txt b/xtoskrnl/CMakeLists.txt index 082b386..08266ea 100644 --- a/xtoskrnl/CMakeLists.txt +++ b/xtoskrnl/CMakeLists.txt @@ -59,6 +59,7 @@ list(APPEND XTOSKRNL_SOURCE ${XTOSKRNL_SOURCE_DIR}/mm/mmgr.cc ${XTOSKRNL_SOURCE_DIR}/mm/paging.cc ${XTOSKRNL_SOURCE_DIR}/mm/pfn.cc + ${XTOSKRNL_SOURCE_DIR}/mm/pte.cc ${XTOSKRNL_SOURCE_DIR}/po/idle.cc ${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/dispatch.cc ${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/exsup.cc diff --git a/xtoskrnl/includes/mm.hh b/xtoskrnl/includes/mm.hh index 2a25fd6..a8cb42e 100644 --- a/xtoskrnl/includes/mm.hh +++ b/xtoskrnl/includes/mm.hh @@ -18,5 +18,6 @@ #include #include #include +#include #endif /* __XTOSKRNL_MM_HH */ diff --git a/xtoskrnl/includes/mm/pte.hh b/xtoskrnl/includes/mm/pte.hh new file mode 100644 index 0000000..fc7f96f --- /dev/null +++ b/xtoskrnl/includes/mm/pte.hh @@ -0,0 +1,39 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/mm/pte.hh + * DESCRIPTION: Page table entry (PTE) support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_MM_PTE_HH +#define __XTOSKRNL_MM_PTE_HH + +#include + + +/* Memory Manager */ +namespace MM +{ + class Pte + { + public: + STATIC XTAPI VOID MapP5E(PVOID StartAddress, + PVOID EndAddress, + PMMP5E TemplateP5e); + STATIC XTAPI VOID MapPDE(PVOID StartAddress, + PVOID EndAddress, + PMMPDE TemplatePde); + STATIC XTAPI VOID MapPPE(PVOID StartAddress, + PVOID EndAddress, + PMMPPE TemplatePpe); + STATIC XTAPI VOID MapPTE(PVOID StartAddress, + PVOID EndAddress, + PMMPTE TemplatePte); + STATIC XTAPI VOID MapPXE(PVOID StartAddress, + PVOID EndAddress, + PMMPXE TemplatePxe); + }; +} + +#endif /* __XTOSKRNL_MM_PTE_HH */ diff --git a/xtoskrnl/mm/pte.cc b/xtoskrnl/mm/pte.cc new file mode 100644 index 0000000..c460807 --- /dev/null +++ b/xtoskrnl/mm/pte.cc @@ -0,0 +1,245 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/mm/pte.cc + * DESCRIPTION: Page table entry (PTE) support + * DEVELOPERS: Aiken Harris + */ + +#include + + +/** + * Maps a range of virtual addresses at the P5E (PML5) level. + * + * @param StartAddress + * The beginning of the virtual address range to map. + * + * @param EndAddress + * The end of the virtual address range to map. + * + * @param TemplateP5e + * A template P5E to use for creating new entries. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Pte::MapP5E(PVOID StartAddress, + PVOID EndAddress, + PMMP5E TemplateP5e) +{ + PMMP5E EndSpace, PointerP5e; + + /* Get P5E addresses */ + PointerP5e = MM::Paging::GetP5eAddress(StartAddress); + EndSpace = MM::Paging::GetP5eAddress(EndAddress); + + /* Iterate over all P5Es */ + while(PointerP5e <= EndSpace) + { + /* Check if P5E is already mapped */ + if(!MM::Paging::PteValid(PointerP5e)) + { + /* Map P5E */ + MM::Paging::SetPte(TemplateP5e, MM::Pfn::AllocateBootstrapPages(1), 0); + *PointerP5e = *TemplateP5e; + + /* Clear the page table */ + RtlZeroMemory(MM::Paging::GetPteVirtualAddress(PointerP5e), MM_PAGE_SIZE); + } + + /* Get next table entry */ + PointerP5e = MM::Paging::GetNextPte(PointerP5e); + } +} + +/** + * Maps a range of virtual addresses at the PDE (Page Directory Entry) level. + * + * @param StartAddress + * The beginning of the virtual address range to map. + * + * @param EndAddress + * The end of the virtual address range to map. + * + * @param TemplatePde + * A template PDE to use for creating new entries. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Pte::MapPDE(PVOID StartAddress, + PVOID EndAddress, + PMMPDE TemplatePde) +{ + PMMPDE EndSpace, PointerPde; + + /* Get PDE addresses */ + PointerPde = MM::Paging::GetPdeAddress(StartAddress); + EndSpace = MM::Paging::GetPdeAddress(EndAddress); + + /* Iterate over all PDEs */ + while(PointerPde <= EndSpace) + { + /* Check if PDE is already mapped */ + if(!MM::Paging::PteValid(PointerPde)) + { + /* Map PDE */ + MM::Paging::SetPte(TemplatePde, MM::Pfn::AllocateBootstrapPages(1), 0); + *PointerPde = *TemplatePde; + + /* Clear the page table */ + RtlZeroMemory(MM::Paging::GetPteVirtualAddress(PointerPde), MM_PAGE_SIZE); + } + + /* Get next table entry */ + PointerPde = MM::Paging::GetNextPte(PointerPde); + } +} + +/** + * Maps a range of virtual addresses at the PPE (Page Directory Pointer Entry) level. + * + * @param StartAddress + * The beginning of the virtual address range to map. + * + * @param EndAddress + * The end of the virtual address range to map. + * + * @param TemplatePpe + * A template PPE to use for creating new entries. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Pte::MapPPE(PVOID StartAddress, + PVOID EndAddress, + PMMPPE TemplatePpe) +{ + PMMPPE EndSpace, PointerPpe; + + /* Get PPE addresses */ + PointerPpe = MM::Paging::GetPpeAddress(StartAddress); + EndSpace = MM::Paging::GetPpeAddress(EndAddress); + + /* Iterate over all PPEs */ + while(PointerPpe <= EndSpace) + { + /* Check if PPE is already mapped */ + if(!MM::Paging::PteValid(PointerPpe)) + { + /* Map PPE */ + MM::Paging::SetPte(TemplatePpe, MM::Pfn::AllocateBootstrapPages(1), 0); + *PointerPpe = *TemplatePpe; + + /* Clear the page table */ + RtlZeroMemory(MM::Paging::GetPteVirtualAddress(PointerPpe), MM_PAGE_SIZE); + } + + /* Get next table entry */ + PointerPpe = MM::Paging::GetNextPte(PointerPpe); + } +} + +/** + * Maps a range of virtual addresses at the PTE (Page Table Entry) level. + * + * @param StartAddress + * The beginning of the virtual address range to map. + * + * @param EndAddress + * The end of the virtual address range to map. + * + * @param TemplatePte + * A template PTE to use for creating new entries. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Pte::MapPTE(PVOID StartAddress, + PVOID EndAddress, + PMMPTE TemplatePte) +{ + PMMPTE EndSpace, PointerPte; + + /* Get PTE addresses */ + PointerPte = MM::Paging::GetPteAddress(StartAddress); + EndSpace = MM::Paging::GetPteAddress(EndAddress); + + /* Iterate over all PTEs */ + while(PointerPte <= EndSpace) + { + /* Check if PTE is already mapped */ + if(!MM::Paging::PteValid(PointerPte)) + { + /* Map PTE */ + MM::Paging::SetPte(TemplatePte, MM::Pfn::AllocateBootstrapPages(1), 0); + *PointerPte = *TemplatePte; + + /* Clear the page table */ + RtlZeroMemory(MM::Paging::GetPteVirtualAddress(PointerPte), MM_PAGE_SIZE); + } + + /* Get next table entry */ + PointerPte = MM::Paging::GetNextPte(PointerPte); + } +} + +/** + * Maps a range of virtual addresses at the PXE (PML4) level. + * + * @param StartAddress + * The beginning of the virtual address range to map. + * + * @param EndAddress + * The end of the virtual address range to map. + * + * @param TemplatePxe + * A template PXE to use for creating new entries. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Pte::MapPXE(PVOID StartAddress, + PVOID EndAddress, + PMMPXE TemplatePxe) +{ + PMMPXE EndSpace, PointerPxe; + + /* Get PXE addresses */ + PointerPxe = MM::Paging::GetPxeAddress(StartAddress); + EndSpace = MM::Paging::GetPxeAddress(EndAddress); + + /* Iterate over all PTEs */ + while(PointerPxe <= EndSpace) + { + /* Check if PTE is already mapped */ + if(!MM::Paging::PteValid(PointerPxe)) + { + /* Map PTE */ + MM::Paging::SetPte(TemplatePxe, MM::Pfn::AllocateBootstrapPages(1), 0); + *PointerPxe = *TemplatePxe; + + /* Clear the page table */ + RtlZeroMemory(MM::Paging::GetPteVirtualAddress(PointerPxe), MM_PAGE_SIZE); + } + + /* Get next table entry */ + PointerPxe = MM::Paging::GetNextPte(PointerPxe); + } +}