From c36e1b5e5e069ce1735dcc2a94aa45ba72ea2441 Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Tue, 9 Dec 2025 00:57:38 +0800 Subject: feat: Initial PMM implementation Introduce the foundational Physical Memory Manager (PMM) and restructure the project for modularity. Implemented basic PMM and related memory management headers (mm/pmm.h, mm/vm.h). Updated Makefile and build process to support new modular structure. --- src/kernel/mm/pmm.cc | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/kernel/mm/pmm.cc (limited to 'src/kernel/mm/pmm.cc') diff --git a/src/kernel/mm/pmm.cc b/src/kernel/mm/pmm.cc new file mode 100644 index 0000000..9b68fcd --- /dev/null +++ b/src/kernel/mm/pmm.cc @@ -0,0 +1,71 @@ +#include "kernel/pmm.h" +#include "drivers/uart.h" + +extern "C" char kernel_end[]; + +namespace PMM +{ + struct Run + { + struct Run *next; + }; + + struct + { + struct Run *freelist; + } kmem; + + inline uint64_t PGROUNDUP(uint64_t a) + { + return (a + PGSIZE - 1) & ~(PGSIZE - 1); + } + + void init() + { + uint64_t start = PGROUNDUP((uint64_t)kernel_end); + + Drivers::uart_puts("PMM: Initializing from"); + + for (uint64_t p = start; p + PGSIZE <= PHYSTOP; p += PGSIZE) + { + free_page((void *)p); + } + } + + void free_page(void* pa) + { + struct Run *r; + if (((uint64_t)pa % PGSIZE) != 0 || (uint64_t)pa < (uint64_t)kernel_end || (uint64_t)pa >= PHYSTOP) + { + Drivers::uart_puts("PMM: Error - Invalid free address\n"); + return; + } + r = (struct Run*)pa; + + r->next = kmem.freelist; + kmem.freelist = r; + + } + + void* alloc_page() + { + struct Run* r; + + r = kmem.freelist; + if (r) + { + kmem.freelist = r->next; + + uint64_t *p = (uint64_t *)r; + for (int i = 0; i < PGSIZE / 8; i++) + { + p[i] = 0; + } + } + else + { + Drivers::uart_puts("PMM: Out of memory!\n"); + } + return (void *)r; + } +} \ No newline at end of file -- cgit v1.2.3