PMM: init (find biggest usable region)
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,4 +1,4 @@
|
|||||||
SOURCES = src/string/string.c src/io/kbd/ps2.c src/io/serial/serial.c src/io/term/printf.c src/io/term/term.c src/idt/idt.c src/mem/gdt/gdt.c src/mem/misc/utils.c src/time/timer.c src/kmain.c
|
SOURCES = src/mem/paging/pmm.c src/string/string.c src/io/kbd/ps2.c src/io/serial/serial.c src/io/term/printf.c src/io/term/term.c src/idt/idt.c src/mem/gdt/gdt.c src/mem/misc/utils.c src/time/timer.c src/kmain.c
|
||||||
|
|
||||||
build:
|
build:
|
||||||
rm -f *.o
|
rm -f *.o
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ enum ErrorCodes
|
|||||||
#include "io/serial/serial.h"
|
#include "io/serial/serial.h"
|
||||||
#include "io/term/printf.h"
|
#include "io/term/printf.h"
|
||||||
|
|
||||||
#define DEBUG(log, ...) fctprintf((void*)&skputc, 0, "debug: [%s]: " log "\n", __FILE__, ##__VA_ARGS__)
|
#define DEBUG(log, ...) fctprintf((void*)&skputc, 0, "debug: [%s]: " log "\r\n", __FILE__, ##__VA_ARGS__)
|
||||||
|
|
||||||
// printf("debug: [%s]: " log "\n", __FILE__, ##__VA_ARGS__);
|
// printf("debug: [%s]: " log "\n", __FILE__, ##__VA_ARGS__);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
15
src/kmain.c
15
src/kmain.c
@@ -10,6 +10,7 @@
|
|||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "time/timer.h"
|
#include "time/timer.h"
|
||||||
#include "io/kbd/ps2.h"
|
#include "io/kbd/ps2.h"
|
||||||
|
#include "mem/paging/pmm.h"
|
||||||
|
|
||||||
// Limine version used
|
// Limine version used
|
||||||
__attribute__((used, section(".limine_requests")))
|
__attribute__((used, section(".limine_requests")))
|
||||||
@@ -29,6 +30,13 @@ static volatile struct limine_memmap_request memmap_request = {
|
|||||||
.revision = 0
|
.revision = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Higher Half Direct Map
|
||||||
|
__attribute__((used, section(".limine_requests")))
|
||||||
|
static volatile struct limine_hhdm_request hhdm_request = {
|
||||||
|
.id = LIMINE_HHDM_REQUEST,
|
||||||
|
.revision = 0
|
||||||
|
};
|
||||||
|
|
||||||
__attribute__((used, section(".limine_requests_start")))
|
__attribute__((used, section(".limine_requests_start")))
|
||||||
static volatile LIMINE_REQUESTS_START_MARKER;
|
static volatile LIMINE_REQUESTS_START_MARKER;
|
||||||
|
|
||||||
@@ -61,13 +69,18 @@ void kmain()
|
|||||||
if (memmap_request.response == NULL) hcf();
|
if (memmap_request.response == NULL) hcf();
|
||||||
memmap_display(memmap_request.response);
|
memmap_display(memmap_request.response);
|
||||||
|
|
||||||
|
if (hhdm_request.response == NULL) hcf();
|
||||||
|
hhdm_display(hhdm_request.response);
|
||||||
|
|
||||||
|
pmm_init(memmap_request.response, hhdm_request.response);
|
||||||
|
|
||||||
CLEAR_INTERRUPTS;
|
CLEAR_INTERRUPTS;
|
||||||
gdt_init();
|
gdt_init();
|
||||||
idt_init();
|
idt_init();
|
||||||
timer_init();
|
timer_init();
|
||||||
SET_INTERRUPTS;
|
SET_INTERRUPTS;
|
||||||
|
|
||||||
//keyboard_init(FR);
|
keyboard_init(FR);
|
||||||
|
|
||||||
// Draw something
|
// Draw something
|
||||||
printf("%s, %s!\n", "Hello", "world");
|
printf("%s, %s!\n", "Hello", "world");
|
||||||
|
|||||||
@@ -111,6 +111,12 @@ void memmap_display(struct limine_memmap_response* response)
|
|||||||
strcpy(type, "UNKNOWN");
|
strcpy(type, "UNKNOWN");
|
||||||
break;
|
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);
|
||||||
|
}
|
||||||
@@ -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);
|
int memcmp(const void* s1, const void* s2, size_t n);
|
||||||
|
|
||||||
void memmap_display(struct limine_memmap_response* response);
|
void memmap_display(struct limine_memmap_response* response);
|
||||||
|
void hhdm_display(struct limine_hhdm_response* hhdm);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -8,10 +8,68 @@ to see which pages are used by kernel/bootloader/mmio/fb etc.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "paging.h"
|
#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,
|
First we'll have to discover the physical memory layout,
|
||||||
and for that we can use a Limine request.
|
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
16
src/mem/paging/pmm.h
Normal 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
|
||||||
Reference in New Issue
Block a user