add mm module to manage free physical page regions
This commit is contained in:
parent
a084ab296c
commit
0f73efbdc3
@ -3,6 +3,7 @@
|
||||
#include "mbinfo.h"
|
||||
#include "klog.h"
|
||||
#include "gdt.h"
|
||||
#include "mm.h"
|
||||
|
||||
void hos_main(uint32_t mbinfo_addr)
|
||||
{
|
||||
@ -17,5 +18,7 @@ void hos_main(uint32_t mbinfo_addr)
|
||||
}
|
||||
klog_init();
|
||||
klog_printf("Welcome to HOS!\n");
|
||||
mm_init();
|
||||
mbinfo_load();
|
||||
klog_printf("Found %dKB of usable RAM\n", mm_get_total_ram() / 1024u);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "mem.h"
|
||||
#include <stdint.h>
|
||||
#include "klog.h"
|
||||
#include "mm.h"
|
||||
|
||||
static uint32_t mbinfo[2048];
|
||||
|
||||
@ -46,6 +47,7 @@ static void mbinfo_process_tag(const multiboot2_info_tag_t * tag)
|
||||
klog_printf("Memory region %16lx : %16lx\n",
|
||||
entry->base_addr,
|
||||
entry->length);
|
||||
mm_register_ram_region(entry->base_addr, entry->length);
|
||||
}
|
||||
entry = (multiboot2_info_memory_map_entry_t *)((uintptr_t)entry + mmap_info->entry_size);
|
||||
}
|
||||
|
74
src/mm.c
Normal file
74
src/mm.c
Normal file
@ -0,0 +1,74 @@
|
||||
#include "mm.h"
|
||||
#include "klog.h"
|
||||
|
||||
#define PAGE_SIZE 4096u
|
||||
|
||||
typedef struct mm_page_entry_s {
|
||||
size_t count;
|
||||
struct mm_page_entry_s * next;
|
||||
} mm_region_entry_t;
|
||||
|
||||
static mm_region_entry_t * mm_next_free_region;
|
||||
static size_t mm_free_page_count;
|
||||
static size_t mm_total_ram;
|
||||
|
||||
extern uint8_t _hos_mem_start;
|
||||
extern uint8_t _hos_mem_end;
|
||||
|
||||
static void mm_add_ram_region(uint32_t base, uint32_t size)
|
||||
{
|
||||
mm_region_entry_t * region = (mm_region_entry_t *)base;
|
||||
size_t pages = size / PAGE_SIZE;
|
||||
region->count = pages;
|
||||
region->next = mm_next_free_region;
|
||||
mm_next_free_region = region;
|
||||
mm_total_ram += size;
|
||||
mm_free_page_count = pages;
|
||||
}
|
||||
|
||||
void mm_register_ram_region(uint64_t base, uint32_t size)
|
||||
{
|
||||
size &= ~(PAGE_SIZE - 1u);
|
||||
/* Ignore any RAM region above 4GB. */
|
||||
if (base >= 0x100000000ull)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ((base + size) > 0x100000000ull)
|
||||
{
|
||||
size = (uint32_t)(0x100000000ull - base);
|
||||
}
|
||||
/* Add regions before and after kernel RAM. */
|
||||
uint32_t region_base = (uint32_t)base;
|
||||
if (region_base < (uint32_t)&_hos_mem_start)
|
||||
{
|
||||
/* RAM region begins before kernel RAM. */
|
||||
uint32_t this_sz = size;
|
||||
if ((region_base + this_sz) > (uint32_t)&_hos_mem_start)
|
||||
{
|
||||
this_sz = (uint32_t)&_hos_mem_start - region_base;
|
||||
}
|
||||
mm_add_ram_region(region_base, this_sz);
|
||||
}
|
||||
if ((region_base + size) > (uint32_t)&_hos_mem_end)
|
||||
{
|
||||
/* RAM region ends after kernel RAM. */
|
||||
uint32_t this_sz = size;
|
||||
if (region_base < (uint32_t)&_hos_mem_end)
|
||||
{
|
||||
this_sz = (region_base + size) - (uint32_t)&_hos_mem_end;
|
||||
region_base = (uint32_t)&_hos_mem_end;
|
||||
}
|
||||
mm_add_ram_region(region_base, this_sz);
|
||||
}
|
||||
}
|
||||
|
||||
void mm_init(void)
|
||||
{
|
||||
mm_total_ram = &_hos_mem_end - &_hos_mem_start;
|
||||
}
|
||||
|
||||
size_t mm_get_total_ram(void)
|
||||
{
|
||||
return mm_total_ram;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user