diff --git a/Makefile b/Makefile index cf2e519..b2ccf57 100644 --- a/Makefile +++ b/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: rm -f *.o diff --git a/src/kernel.h b/src/kernel.h index e1cf0b3..0daeeef 100644 --- a/src/kernel.h +++ b/src/kernel.h @@ -13,7 +13,7 @@ enum ErrorCodes #include "io/serial/serial.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__); #endif diff --git a/src/kmain.c b/src/kmain.c index 1bff270..1ea9f90 100644 --- a/src/kmain.c +++ b/src/kmain.c @@ -10,6 +10,7 @@ #include "kernel.h" #include "time/timer.h" #include "io/kbd/ps2.h" +#include "mem/paging/pmm.h" // Limine version used __attribute__((used, section(".limine_requests"))) @@ -29,6 +30,13 @@ static volatile struct limine_memmap_request memmap_request = { .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"))) static volatile LIMINE_REQUESTS_START_MARKER; @@ -61,13 +69,18 @@ void kmain() if (memmap_request.response == NULL) hcf(); 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; gdt_init(); idt_init(); timer_init(); SET_INTERRUPTS; - //keyboard_init(FR); + keyboard_init(FR); // Draw something printf("%s, %s!\n", "Hello", "world"); diff --git a/src/mem/misc/utils.c b/src/mem/misc/utils.c index adbf38e..227dab0 100644 --- a/src/mem/misc/utils.c +++ b/src/mem/misc/utils.c @@ -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); } \ No newline at end of file diff --git a/src/mem/misc/utils.h b/src/mem/misc/utils.h index 1b01ca3..169d88d 100644 --- a/src/mem/misc/utils.h +++ b/src/mem/misc/utils.h @@ -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 \ No newline at end of file diff --git a/src/mem/paging/pmm.c b/src/mem/paging/pmm.c index 0028cda..0f1e956 100644 --- a/src/mem/paging/pmm.c +++ b/src/mem/paging/pmm.c @@ -8,10 +8,68 @@ to see which pages are used by kernel/bootloader/mmio/fb etc. */ #include "paging.h" +#include +#include +#include +#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[]; \ No newline at end of file +/* +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; ientry_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); +} \ No newline at end of file diff --git a/src/mem/paging/pmm.h b/src/mem/paging/pmm.h new file mode 100644 index 0000000..d2c722f --- /dev/null +++ b/src/mem/paging/pmm.h @@ -0,0 +1,16 @@ +#ifndef PAGING_PMM_H +#define PAGING_PMM_H + +#include + +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 \ No newline at end of file