From 5cee647ff0794f42b9f2f29dcc558cb96951396c Mon Sep 17 00:00:00 2001 From: Tomas Date: Fri, 28 Mar 2025 11:30:43 +0100 Subject: [PATCH] Added basic paging.h & paging.c --- kernel/include/bootloader.h | 7 ++++--- kernel/include/paging.h | 25 +++++++++++++++++++++++++ kernel/src/bootloader.c | 19 +++++++++++++++++-- kernel/src/kernel.c | 22 +++------------------- kernel/src/paging.c | 27 +++++++++++++++++++++++++++ kernel/src/pmm.c | 29 +++++++++++++++++------------ 6 files changed, 93 insertions(+), 36 deletions(-) create mode 100644 kernel/include/paging.h create mode 100644 kernel/src/paging.c diff --git a/kernel/include/bootloader.h b/kernel/include/bootloader.h index 2383072..68efaa7 100644 --- a/kernel/include/bootloader.h +++ b/kernel/include/bootloader.h @@ -16,12 +16,13 @@ #define BOOT_MMAP_NVS 4 #define BOOT_MMAP_BADRAM 5 +#define BOOT_MAX_MMAP_ENTRIES 128 + // A memory map entry struct boot_memmap { - uint32_t skip; // Used for skipping (may be padded for alignment) uint64_t base; // Memory region address uint64_t size; // Memory region length - uint32_t type; // Memory region type + uint8_t type; // Memory region type } __packed; /* @@ -39,7 +40,7 @@ struct boot_info { uint8_t bootPart2; uint8_t bootPart3; char* cmdline; - uint32_t memmap; + struct boot_memmap* memmap; size_t memmapLen; char* bootname; } __packed; diff --git a/kernel/include/paging.h b/kernel/include/paging.h new file mode 100644 index 0000000..963abfb --- /dev/null +++ b/kernel/include/paging.h @@ -0,0 +1,25 @@ +#ifndef _PAGING_H +#define _PAGING_H + +#include + +#define PAGE_SIZE 4096 + +#define PHYS_ADDR(_a) ((_a) & ~0xfff) + +#define PAGE_FLAG_PRESENT (1 << 0) +#define PAGE_FLAG_WRITE (1 << 1) +#define PAGE_FLAG_USER (1 << 2) +#define PAGE_FLAG_PWT (1 << 3) +#define PAGE_FLAG_NOCACHE (1 << 4) +#define PAGE_FLAG_ACCESSED (1 << 5) +#define PAGE_FLAG_DIRTY (1 << 6) +#define PAGE_FLAG_4MB (1 << 7) +#define PAGE_FLAG_GLOBAL (1 << 8) + +// Defined in entry.s for initial paging +extern uint32_t init_pagedir[1024]; + +int pag_init(void); + +#endif diff --git a/kernel/src/bootloader.c b/kernel/src/bootloader.c index ba08013..9446fae 100644 --- a/kernel/src/bootloader.c +++ b/kernel/src/bootloader.c @@ -1,7 +1,9 @@ #include #include #include +#include +struct boot_memmap memmap[BOOT_MAX_MMAP_ENTRIES]; struct boot_info bootloader; // TODO: @@ -39,8 +41,21 @@ int boot_initMB1(void* ptr, uint32_t magic) { // mmap_* fields are valid if (mbi->flags & MULTIBOOT_INFO_MEM_MAP) { - bootloader.memmap = mbi->mmap_addr; - bootloader.memmapLen = mbi->mmap_length; + bootloader.memmap = &memmap[0]; + + size_t i = 0; + multiboot_memory_map_t* entry = (multiboot_memory_map_t*)mbi->mmap_addr; + uint32_t mapLim = mbi->mmap_addr + mbi->mmap_length; + + while ((uint32_t)entry < mapLim) { + bootloader.memmap[i].base = entry->addr; + bootloader.memmap[i].size = entry->len; + bootloader.memmap[i].type = (uint8_t)entry->type; + + entry++; + i++; + } + bootloader.memmapLen = i; } // TODO: drives_* diff --git a/kernel/src/kernel.c b/kernel/src/kernel.c index bf00c10..25df395 100644 --- a/kernel/src/kernel.c +++ b/kernel/src/kernel.c @@ -1,8 +1,10 @@ #include #include +#include #include #include #include +#include #include // TODO: Commented out stuff @@ -27,27 +29,9 @@ void kmain(void* ptr, uint32_t magic) { gdt_init(); isr_init(); - // pag_init(); + pag_init(); debugf("Basic initialization complete!\n"); - - struct boot_memmap* entry; - for ( - entry = (struct boot_memmap*)bootloader.memmap; - (uint64_t)entry < bootloader.memmap + bootloader.memmapLen; - entry = (struct boot_memmap*)((uint64_t)entry + entry->skip + sizeof(entry)) - ) { - - debugf("[Region] base: %x size: %x b type: ", entry->base, entry->size); - switch (entry->type) { - case BOOT_MMAP_AVAILABLE: debugf("Available\n"); break; - case BOOT_MMAP_RESERVED: debugf("Reserved\n"); break; - case BOOT_MMAP_ACPI_RECLAIM: debugf("ACPI Reclaim\n"); break; - case BOOT_MMAP_NVS: debugf("NVS\n"); break; - case BOOT_MMAP_BADRAM: debugf("Bad RAM\n"); break; - default: debugf("Invalid type\n"); break; - } - } panic("kmain() reached end."); diff --git a/kernel/src/paging.c b/kernel/src/paging.c new file mode 100644 index 0000000..aca10d3 --- /dev/null +++ b/kernel/src/paging.c @@ -0,0 +1,27 @@ +#include +#include +#include + +// Invalidates the pagedir entry in the CPUs TLB cache +static inline void invalidate(uint32_t vaddr) { + __asm__ volatile ("invlpg %0" : : "m"(vaddr)); +} + +int pag_init(void) { + // Unmap first MB + init_pagedir[0] = 0; + invalidate(0); + + /* + * Recursive table mapping + * We map the last pagetab to the pagedir itself, so it acts + * as a pagetab even though it's a pagedir. This maps it to + * the virtual address 0xFFFFF000. + */ + init_pagedir[1023] = ((uint32_t)init_pagedir - 0xC0000000) | + PAGE_FLAG_PRESENT | PAGE_FLAG_WRITE; + invalidate(0xFFFFF000); + + return 0; +} + diff --git a/kernel/src/pmm.c b/kernel/src/pmm.c index c814e86..b35f0f5 100644 --- a/kernel/src/pmm.c +++ b/kernel/src/pmm.c @@ -1,22 +1,27 @@ -#include +#include #include +#include #include -// Helpers -#define SET_BLOCK(_b) memmap[(_b) / 32] |= (1 << ((_b) % 32)) -#define USET_BLOCK(_b) memmap[(_b) / 32] &= ~(1 << ((_b) % 32)) -#define TEST_BLOCK(_b) ((memmap[(_b) % 32] & (1 << ((_b) % 32))) ? 1 : 0) +// Bitmap & helpers +uint32_t* bitmap = NULL; +#define SET_BLOCK(_b) bitmap[(_b) / 32] |= (1 << ((_b) % 32)) +#define USET_BLOCK(_b) bitmap[(_b) / 32] &= ~(1 << ((_b) % 32)) +#define TEST_BLOCK(_b) ((bitmap[(_b) % 32] & (1 << ((_b) % 32))) ? 1 : 0) -// Memory manager bitmap -uint32_t* memmap = NULL; +// Status size_t usedBlocks = 0; size_t maxBlocks = 0; -// TODO: improve these hardcoded values int pmm_init(void) { - memmap = NULL; // Memory map location - usedBlocks = 0; - maxBlocks = 0; // TODO + size_t totalmem = (bootloader.memLower + bootloader.memUpper) * 1024; + maxBlocks = totalmem / PMM_BS; + usedBlocks = maxBlocks; + + // TODO: + bitmap = (uint32_t*)NULL; + memset(bitmap, 0, maxBlocks / PMM_BPB); + return 0; } @@ -27,7 +32,7 @@ int findFreeBlocks(size_t blockCount) { uint32_t freeCount = 0; for (size_t i = 0; i < max; i++) { // We don't have to check, cause it's all reserved - if (memmap[i] == 0xffffffff) continue; + if (bitmap[i] == 0xffffffff) continue; for (uint8_t j = 0; j < 32; j++) { if (TEST_BLOCK(i * PMM_BPB + j)) freeCount++;