Files
nt-lite/code/kernel/mm_virt.h
T

100 lines
4.9 KiB
C

#pragma once
// mm_virt.h - virtual memory manager (VMM)
// Manages the single shared PML4, kernel pool, and user heap.
#include <stdint.h>
#include <stddef.h>
#include <mm_phys.h>
#include <ke_status.h>
// ---------------------------------------------------------------------------
// Page flags (x86-64 PTE bits)
// ---------------------------------------------------------------------------
#define PAGE_PRESENT (1ULL << 0)
#define PAGE_WRITE (1ULL << 1)
#define PAGE_USER (1ULL << 2)
#define PAGE_NOCACHE (1ULL << 4)
#define PAGE_NX (1ULL << 63)
// ---------------------------------------------------------------------------
// Virtual address space constants
// ---------------------------------------------------------------------------
#define USER_BASE 0x0000000000001000ULL
#define USER_LIMIT 0x00007FFFFFFFF000ULL
#define KERNEL_BASE 0xFFFF800000000000ULL
#define PHYS_MAP_BASE 0xFFFF880000000000ULL
#define POOL_BASE 0xFFFFC00000000000ULL
#define POOL_LIMIT 0xFFFFE00000000000ULL
// ---------------------------------------------------------------------------
// Initialisation
// ---------------------------------------------------------------------------
// Called by KernelMain after MmInitializePhysical.
// bootPml4Phys: the PML4 set up by the bootloader.
// poolSize: initial reservation for kernel pool (bytes, page-aligned).
void MmInitializeVirtual(PHYSICAL_ADDRESS bootPml4Phys, size_t poolSize);
// Install the shared PML4 into CR3. Called once at the end of KernelMain init.
void MmActivate(void);
// ---------------------------------------------------------------------------
// Page mapping
// ---------------------------------------------------------------------------
__declspec(dllexport) KSTATUS MmMapPage(uintptr_t virt, PHYSICAL_ADDRESS phys, uint64_t flags);
__declspec(dllexport) KSTATUS MmUnmapPage(uintptr_t virt);
// Modify protection flags on an already-mapped virtual range.
// 'flags' is the complete new set of PAGE_* bits - it replaces the old flags
// entirely (except the physical address, which is preserved).
// Returns STATUS_NOT_FOUND if any page in the range is not mapped.
__declspec(dllexport) KSTATUS MmSetPageProtect(uintptr_t virt, size_t size, uint64_t flags);
// Walk the page tables to translate a virtual address to physical.
// Returns 0 if the address is not mapped.
__declspec(dllexport) PHYSICAL_ADDRESS MmGetPhysicalAddress(uintptr_t virt);
// ---------------------------------------------------------------------------
// User/kernel copy boundary helpers
// ---------------------------------------------------------------------------
// MmQueryPage returns the physical address and effective PAGE_* bits for a
// mapped virtual address. The reported PAGE_USER/PAGE_WRITE bits account for
// every page-table level, not just the leaf entry.
__declspec(dllexport) KSTATUS MmQueryPage(uintptr_t virt, PHYSICAL_ADDRESS* physOut, uint64_t* flagsOut);
// Probe a user virtual range without copying it. These functions only accept
// lower-half user mappings with PAGE_USER set; MmProbeUserWrite additionally
// requires PAGE_WRITE.
__declspec(dllexport) KSTATUS MmProbeUserRead(const void* ptr, size_t size);
__declspec(dllexport) KSTATUS MmProbeUserWrite(void* ptr, size_t size);
// Copy through the syscall trust boundary. Kernel subsystems should receive
// kernel-owned buffers, not raw user pointers, unless explicitly documented.
__declspec(dllexport) KSTATUS CopyFromUser(void* kernelDst, const void* userSrc, size_t size);
__declspec(dllexport) KSTATUS CopyToUser(void* userDst, const void* kernelSrc, size_t size);
// ---------------------------------------------------------------------------
// Kernel pool - ring 0 only, never PAGE_USER.
// Best-fit free-list allocator, thread-safe via spinlock.
// ---------------------------------------------------------------------------
__declspec(dllexport) void* MmAllocatePool(size_t size);
__declspec(dllexport) void MmFreePool(void* ptr);
__declspec(dllexport) void* MmReallocatePool(void* ptr, size_t newSize);
// ---------------------------------------------------------------------------
// User heap - shared flat space, ring 3 accessible.
// Allocations are writable user pages with NX set by default; PE image
// sections opt back into execution through the loader.
// ---------------------------------------------------------------------------
__declspec(dllexport) void* MmAllocateUserMemory(size_t size);
__declspec(dllexport) void MmFreeUserMemory(void* ptr);
__declspec(dllexport) void* MmReallocateUserMemory(void* ptr, size_t newSize);
// Page-aligned user image mapping. PE section protection is page based, so
// executable images must not be allocated from the normal sub-page heap.
__declspec(dllexport) void* MmAllocateUserImage(size_t size);
__declspec(dllexport) void MmFreeUserImage(void* ptr, size_t size);
size_t MmGetKernelPoolUsage(void);
size_t MmGetUserHeapUsage(void);