diff --git a/kernel/arch/paging/paging.c b/kernel/arch/paging/paging.c index 4ceafb1..3751201 100644 --- a/kernel/arch/paging/paging.c +++ b/kernel/arch/paging/paging.c @@ -6,50 +6,3 @@ //extern uint32_t endkernel; // found in link.ld -/** - * The page table must be page aligned (aligned at 4KiB) - * - * - * This is a temporary solution, as we want a page frame allocator, to properly get page frames.. but this works for now - */ -uint32_t page_directory[PAGE_DIRECTORY_ENTRIES] __attribute__((aligned(4096))); - -uint32_t first_page_table[PAGE_TABLE_ENTRIES] __attribute__((aligned(4096))); - -void setup_page_table(void) -{ - uint32_t i; - for (i = 0; i < PAGE_TABLE_ENTRIES; i++) { - first_page_table[i] = (i * 0x1000) | 3; // supervisor, r/w, present - } - puts("test"); -} - -void setup_page_dir(void) -{ - setup_page_table(); - /** - * Now that we have a page directory, we need to blank it. - * - * The page directory should have exactly 1024 entries. We will set each entry to not present, so that the if the - * MMU looks for that page table, it will see that it is not there yet. - */ - int i; - for (i = 0; i < PAGE_DIRECTORY_ENTRIES; i++) { - // This sets the following flags to the pages: - // Supervisor: Only kernel-mode can access them - // Write Enabled: It can be both read from and written to - // Not Present: The page table is not present - page_directory[i] = 0x00000002; - } - - page_directory[0] = ((uint32_t) first_page_table) | 3; -} - -void setup_paging(void) -{ - setup_page_dir(); - - load_page_directory(page_directory); - enable_paging(); -} diff --git a/kernel/arch/pmm/pmm.c b/kernel/arch/pmm/pmm.c new file mode 100644 index 0000000..1b2e0bb --- /dev/null +++ b/kernel/arch/pmm/pmm.c @@ -0,0 +1,66 @@ +#include + +/** + * What i want to do is create a linked list of all the memory structures + * + * Theres one at the very start of the memory + * + * one at 1MB + * + * and then one provided by ram. + * + * + * So the idea is to create a way to access memory through this such that, + * when you give a bit block number, it'll go through the first item in the linked list, if the block is out of that range, it + * traverses to the next node, tries to find it there, and then continues until it either runs out of memory, or finds a location + */ + +#define PMM_PAGE_SIZE 4096 + +struct pmm_mem_info { + uint64_t startaddr; + uint64_t len; // in kb + uint32_t* bitmap; +}; + +#define PMM_GET_MEM_BLOCKS(x) x.len / PMM_PAGE_SIZE + +struct pmm_mem_info main_mem; + +void __pmm_set(int bit, uint32_t* bitmap) +{ + bitmap[bit / 32] |= (1 << (bit % 32)); +} + +void __pmm_unset(int bit, uint32_t* bitmap) +{ + bitmap[bit / 32] &= ~(1 << (bit % 32)); +} + +void __pmm_first_free(struct pmm_mem_info mem_block) +{ + for (uint32_t i = 0; i < PMM_GET_MEM_BLOCKS(mem_block) / 32; i++) { + + } +} + +void pmm_set(int bit) +{ + /** + * Here we want to calculate if the bit is over the length + * subtract the length and bit amount so that we compensate for the bit map + * + * i.e. (length / 4096) == amount of blocks in that specific mem region + * if (bit > amt of blocks), + * go to next node, subtract amt of blocks from bit, and pass that + * + * below is merely a temporary solution + */ + __pmm_set(bit, main_mem.bitmap); +} + +void pmm_unset(int bit) +{ + // TODO: same as above + __pmm_unset(bit, main_mem.bitmap); +} diff --git a/kernel/include/kernel/_kernel.h b/kernel/include/kernel/_kernel.h index 694beda..8109b77 100644 --- a/kernel/include/kernel/_kernel.h +++ b/kernel/include/kernel/_kernel.h @@ -7,6 +7,5 @@ void kwarn(const char*); void kinfo(const char*); - #endif diff --git a/kernel/include/kernel/paging.h b/kernel/include/kernel/paging.h index d41c280..eb3b70e 100644 --- a/kernel/include/kernel/paging.h +++ b/kernel/include/kernel/paging.h @@ -3,14 +3,4 @@ #ifndef ARCH_PAGING_H #define ARCH_PAGING_H -#define PAGE_TABLE_ENTRIES 1024 -#define PAGE_DIRECTORY_ENTRIES 1024 - -void load_page_directory(uint32_t*); - -void enable_paging(); - - -void setup_paging(void); - #endif diff --git a/kernel/include/kernel/pmm.h b/kernel/include/kernel/pmm.h new file mode 100644 index 0000000..68f9496 --- /dev/null +++ b/kernel/include/kernel/pmm.h @@ -0,0 +1,20 @@ +#include +#include +#include + +#ifndef ARCH_PMM_H +#define ARCH_PMM_H + +#define PMM_BLOCKS_PER_BYTE 8 // This is for the Bitmap +#define PMM_BLOCK_SIZE 4096 // 4KiB +#define PMM_BLOCK_ALIGN (PMM_BLOCK_SIZE) // must be aligned at 4KiB + +void set_grub_mem_map(uint32_t addr, uint32_t len); +uint32_t pmm_get_block_count(void); + +int pmm_first_free(void); +int pmm_first_free_s(size_t pages); + +void pmm_init(size_t mem_size, uint32_t* bitmap); + +#endif diff --git a/kernel/kmain.c b/kernel/kmain.c index 820ecb4..dc49b03 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "multiboot.h" @@ -19,44 +20,32 @@ void verify_memmap(multiboot_info_t* mbd, uint32_t magic) { if (magic != MULTIBOOT_BOOTLOADER_MAGIC) panic("Invalid magic number!"); - else - printf("%2\n", magic); if (!(mbd->flags >> 6 & 0x1)) panic("Invalid memory map given by GRUB bootloader!"); -#ifdef __TESTING__ + if (!(mbd->flags & (1 << 0))) + panic("Memory info not passed to kernel!"); + puts("Printing available memory map..."); uint32_t i; for (i = 0; i < mbd->mmap_length; i += sizeof(multiboot_memory_map_t)) { multiboot_memory_map_t* mmmt = (multiboot_memory_map_t*) (mbd->mmap_addr + i); - printf("Start Addr: %4 | Length: %4 | Size: %2 | Type: ", - mmmt->addr, mmmt->len, mmmt->size); - switch (mmmt->type) { - case MULTIBOOT_MEMORY_AVAILABLE: - puts("Available"); - break; - case MULTIBOOT_MEMORY_RESERVED: - puts("Reserved"); - break; - case MULTIBOOT_MEMORY_ACPI_RECLAIMABLE: - puts("ACPI Reclaimable"); - break; - case MULTIBOOT_MEMORY_NVS: - puts("NVS"); - break; - case MULTIBOOT_MEMORY_BADRAM: - puts("Bad ram"); - break; - default: - puts("Unknown"); - break; - } + printf("Start Addr: %4 | Length: %4 | Size: %2 | Type: %d\n", + mmmt->addr, mmmt->len, mmmt->size, mmmt->type); - // if (mmmt->type == MULTIBOOT_MEMORY_AVAILABLE) -> DO SOMETHING + // mmmt-> len is in bytes (according to multiboot specification0 + // mmmt->len / 1024 == kib // block size == blocks + + if (mmmt->type == MULTIBOOT_MEMORY_AVAILABLE && (mmmt->addr == 0x100000)) { + // This is the main mem address we want + // TODO: this is probably flaky, so i want to find a better and more reliable way to do this + set_grub_mem_map(mmmt->addr, mmmt->len); + } } -#endif + + printf("%2 %2\n", mbd->mem_lower, mbd->mem_upper); } void _main(multiboot_info_t* mbd, uint32_t magic) @@ -65,6 +54,7 @@ void _main(multiboot_info_t* mbd, uint32_t magic) terminal_initialize(); serial_initialize(); #endif + printf("%2, %2\n", mbd->mem_lower, mbd->mem_upper); verify_memmap(mbd, magic); @@ -76,7 +66,7 @@ void _main(multiboot_info_t* mbd, uint32_t magic) serial_initialize(); #endif - setup_paging(); + //setup_paging(); init_kb();