Fix PMM for real HW + serial lock

This commit is contained in:
2026-03-19 16:54:23 +01:00
parent b77c53ae99
commit 6a82d581fb
9 changed files with 52 additions and 45 deletions

View File

@@ -11,6 +11,7 @@ it will probably need to get some info from Limine,
to see which pages are used by kernel/bootloader/mmio/fb etc.
*/
#include "config.h"
#include <mem/paging.h>
#include <limine.h>
#include <stddef.h>
@@ -24,10 +25,11 @@ First we'll have to discover the physical memory layout,
and for that we can use a Limine request.
*/
// DEPRECATED
struct limine_memmap_entry* biggest_entry;
/*
* pmm_find_biggest_usable_region - Finding the biggest free memory region
* pmm_find_biggest_usable_region - Finding the biggest free memory region (DEPRECATED)
* @memmap: Limine memory map
* @hhdm: Limine HHDM offset
*
@@ -99,19 +101,32 @@ void pmm_free(uintptr_t addr)
* This function marks the biggest memory region as
* free, so we can use it in pmm_alloc.
*/
static void pmm_init_freelist()
static void pmm_init_freelist(struct limine_memmap_response* memmap)
{
// We simply call pmm_free() on each page that is marked USABLE
// in our big memory region.
uint64_t base = ALIGN_UP(biggest_entry->base, PAGE_SIZE);
uint64_t end = ALIGN_DOWN(biggest_entry->base + biggest_entry->length, PAGE_SIZE);
uint64_t total_pages = 0;
uint64_t page_count=0;
for (uint64_t addr = base; addr < end; addr += PAGE_SIZE) {
pmm_free(addr);
page_count++;
for (size_t i=0; i<memmap->entry_count; i++) {
struct limine_memmap_entry* entry = memmap->entries[i];
if (entry->type == LIMINE_MEMMAP_USABLE) {
uint64_t base = ALIGN_UP(entry->base, PAGE_SIZE);
uint64_t end = ALIGN_DOWN(entry->base + entry->length, PAGE_SIZE);
if (end > PAGING_MAX_PHYS) {
end = PAGING_MAX_PHYS;
}
// Region above PAGING_MAX_PHYS
if (base >= end) continue;
for (uint64_t addr = base; addr < end; addr += PAGE_SIZE) {
pmm_free(addr);
total_pages++;
}
}
}
DEBUG("%u frames in freelist, available for use (%u bytes)", page_count, page_count*PAGE_SIZE);
DEBUG("%u frames in freelist, %u bytes available (%u MB)", total_pages, total_pages*PAGE_SIZE, total_pages*PAGE_SIZE/1000000);
}
/*
@@ -124,9 +139,9 @@ static void pmm_init_freelist()
void pmm_init(struct boot_context boot_ctx)
{
hhdm_off = boot_ctx.hhdm->offset;
pmm_find_biggest_usable_region(boot_ctx.mmap, boot_ctx.hhdm);
//pmm_find_biggest_usable_region(boot_ctx.mmap, boot_ctx.hhdm);
// Now we have biggest USABLE region,
// so to populate the free list we just iterate through it
pmm_init_freelist();
pmm_init_freelist(boot_ctx.mmap);
}