// // Created by rick on 22-04-20. // #include #include #include #include #include #include #define MEMMAP_ENTRIES 16 #define MMAP_TYPE_UNDEFINED 0 #define MMAP_TYPE_AVAILABLE 1 #define MMAP_TYPE_RESERVED 2 #define MMAP_TYPE_ACPI_RECLAIMABLE 3 #define MMAP_TYPE_NVS 4 #define MMAP_TYPE_BADRAM 5 #define MMAP_TYPE_KERNEL 6 #define MMAP_TYPE_PAGING 7 typedef struct { uint32_t address; uint32_t length; uint32_t type; } att_packed mmap_entry; int last_memmap_entry = 0; mmap_entry memmap[MEMMAP_ENTRIES] = { {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, }; void use_mmap_entry(struct multiboot_mmap_entry *entry) { mmap_entry *mm_entry = &memmap[last_memmap_entry++]; mm_entry->address = (void *) entry->addr; mm_entry->length = entry->len; mm_entry->type = entry->type; // check if the entry overlaps with the kernel address space if (kernel_start >= mm_entry->address && kernel_start <= mm_entry->address + mm_entry->length) { uint32_t page_after_kernel = kernel_end + PAGE_SIZE & ~(PAGE_SIZE - 1); uint32_t kernel_size_full_pages = page_after_kernel - mm_entry->address; // todo make this something proper struct multiboot_mmap_entry extra_entry; extra_entry.size = entry->size; extra_entry.type = entry->type; extra_entry.addr = page_after_kernel; extra_entry.len = entry->size - kernel_size_full_pages; use_mmap_entry(&extra_entry); mm_entry->length = kernel_size_full_pages; mm_entry->type = MMAP_TYPE_KERNEL; } } void mmap_init_multiboot(struct multiboot_mmap_entry *entries, uint32_t count) { for (uint32_t i = 0; i < count; ++i) { use_mmap_entry(&entries[i]); } // init page manager for (int i = 0; i < last_memmap_entry; ++i) { mmap_entry *entry = &memmap[i]; if (entry->type != MMAP_TYPE_AVAILABLE) { continue; } if (entry->address < kernel_start) { continue; // skip for now } pmm_init((void *) entry->address, entry->length); entry->type = MMAP_TYPE_PAGING; } } void print_mmap_info() { printf("Kernel start: %8x\n" "Kernel end: %8x\n", kernel_start, kernel_end); for (int i = 0; i < 16; ++i) { if (memmap[i].type == 0) { break; } printf("Idx: %d\n" "Address: %8x\n" "Length: %8x\n" "Type: %d\n\n", i, memmap[i].address, memmap[i].length, memmap[i].type); } }