PMM: init (find biggest usable region)

This commit is contained in:
2025-12-31 12:02:41 +01:00
parent 8f5e2eae3e
commit 05a862e97a
7 changed files with 99 additions and 5 deletions

View File

@@ -111,6 +111,12 @@ void memmap_display(struct limine_memmap_response* response)
strcpy(type, "UNKNOWN");
break;
}
DEBUG("entry %u: [%016x | %u bytes] - %s", i, entry->base, entry->length, type);
DEBUG("entry %02u: [0x%016x | %016u bytes] - %s", i, entry->base, entry->length, type);
}
}
// Display the HHDM
void hhdm_display(struct limine_hhdm_response* hhdm)
{
DEBUG("Got HHDM revision=%u offset=0x%p", hhdm->revision, hhdm->offset);
}

View File

@@ -9,5 +9,6 @@ void* memmove(void *dest, const void* src, size_t n);
int memcmp(const void* s1, const void* s2, size_t n);
void memmap_display(struct limine_memmap_response* response);
void hhdm_display(struct limine_hhdm_response* hhdm);
#endif

View File

@@ -8,10 +8,68 @@ to see which pages are used by kernel/bootloader/mmio/fb etc.
*/
#include "paging.h"
#include <limine.h>
#include <stddef.h>
#include <kernel.h>
#include "../misc/utils.h"
/*
First we'll have to discover the physical memory layout,
and for that we can use a Limine request.
*/
uint64_t pages_bitmap[];
/*
We will look for the biggest usable physical memory region
and use this for the bitmap. The reserved memory will be ignored.
*/
struct usable_memory* usable_mem;
struct limine_memmap_entry* biggest_entry;
uint64_t* bitmap;
static void pmm_allocate_bitmap(struct limine_hhdm_response* hhdm)
{
uint64_t pages = biggest_entry->length / PAGE_SIZE;
DEBUG("we need %u pages (bits) that will fit in %u uint64_t", pages, pages/64);
bitmap = (uint64_t*)(biggest_entry->base + hhdm->offset);
DEBUG("bitmap will live at 0x%p", bitmap);
// All pages are marked free since we're in a USABLE region
memset(bitmap, 0x00, pages/64);
}
static void pmm_find_biggest_usable_region(struct limine_memmap_response* memmap, struct limine_hhdm_response* hhdm)
{
// Max length of a usable memory region
uint64_t length_max = 0;
uint64_t offset = hhdm->offset;
DEBUG("Usable Memory:");
for (size_t i=0; i<memmap->entry_count; i++)
{
struct limine_memmap_entry* entry = memmap->entries[i];
if (entry->type == LIMINE_MEMMAP_USABLE)
{
DEBUG("0x%p-0x%p mapped at 0x%p-0x%p", entry->base, entry->base+entry->length,
entry->base+offset, entry->base+entry->length+offset);
if (entry->length > length_max)
{
length_max = entry->length;
biggest_entry = entry;
}
}
}
DEBUG("Biggest usable memory region:");
DEBUG("0x%p-0x%p mapped at 0x%p-0x%p", biggest_entry->base, biggest_entry->base + biggest_entry->length,
biggest_entry->base+offset, biggest_entry->base+biggest_entry->length+offset);
}
void pmm_init(struct limine_memmap_response* memmap, struct limine_hhdm_response* hhdm)
{
pmm_find_biggest_usable_region(memmap, hhdm);
pmm_allocate_bitmap(hhdm);
}

16
src/mem/paging/pmm.h Normal file
View File

@@ -0,0 +1,16 @@
#ifndef PAGING_PMM_H
#define PAGING_PMM_H
#include <limine.h>
void pmm_init(struct limine_memmap_response* memmap, struct limine_hhdm_response* hhdm);
// Might be upgraded to a freelist later.
// For now, we can take the biggest usable region and we will be fine.
struct usable_memory
{
uint64_t base; // physical
uint64_t length;
};
#endif