#include "memory.h" #include "string.h" #include "utils.h" #include uint32_t *page_directory = &boot_page_directory; uint32_t page_table_default[1024] __attribute__((aligned(PAGE_SIZE))); uint32_t frame_zones_page_table[1024] __attribute__((aligned(PAGE_SIZE))); uint32_t mem_size; struct frame_zone *head; static void lst_add_back(struct frame_zone **root, struct frame_zone *element) { if (!*root) { *root = element; return; } struct frame_zone *it = *root; while (it->next) it = it->next; it->next = element; } static void add_frame_node(multiboot_memory_map_t *mmmt) { static uint32_t index; /** * # = kernel code * - = blank */ uint64_t start_addr = mmmt->addr; uint64_t end_addr = mmmt->addr + mmmt->len; uint64_t len = mmmt->len; /** Kernel code cover all the block * this situation: * ####################### */ if (KERNEL_START <= start_addr && KERNEL_END >= end_addr) return; /** Kernel code start on the block * this situation: * --------############### */ if (KERNEL_START > start_addr && KERNEL_START <= end_addr) { len = ROUND_FLOOR(KERNEL_START - start_addr, PAGE_SIZE); } /** Kernel code end on the block * this situation: * ###############-------- */ if (KERNEL_START <= start_addr && KERNEL_END > start_addr && KERNEL_END <= end_addr) { len = ROUND_CEIL(len - (KERNEL_END - start_addr), PAGE_SIZE) - PAGE_SIZE; // cringe but ROUND_FLOOR is un poquito crampte start_addr = ROUND_CEIL(KERNEL_END, PAGE_SIZE); } end_addr = ROUND_CEIL(start_addr + len, PAGE_SIZE); init_page_table(frame_zones_page_table, 0); page_directory[1022] = ((uint32_t)frame_zones_page_table - HEAP_END) | 0x03; frame_zones_page_table[index] = ((uint32_t)start_addr & PAGE_MASK) | INIT_FLAGS; struct frame_zone *current = (struct frame_zone *)GET_PAGE_ADDR(1022, index++); current->frame_table = (uint8_t *)current + sizeof(struct frame_zone); /** 8 is cause we are using uint8_t nb_frame = size / (PAGE_SIZE + 1 / 8) cause we are using non decimal number nb_frame = ((size * 8) / (PAGE_SIZE * 8 + 1)) */ const uint32_t nb_frame = ((len * 8) / (PAGE_SIZE * 8 + 1)); current->first_free_frame = 0; current->next = NULL; current->remaining_frames = nb_frame; current->total_frames = nb_frame; memset(current->frame_table, 0, nb_frame * sizeof(*current->frame_table)); uint32_t i = 1; for (; i < CEIL(nb_frame, PAGE_SIZE); i++) frame_zones_page_table[index + i] = ((uint32_t)(start_addr + i * PAGE_SIZE) & PAGE_MASK) | INIT_FLAGS; current->addr = (void *)start_addr + i * PAGE_SIZE; index += i - 1; lst_add_back(&head, current); } static void init_frame_zones(void) { for (uint32_t i = 0; i < mmap_length; i++) { multiboot_memory_map_t *mmmt = (multiboot_memory_map_t *)mmap_addr + i; if (mmmt->type == MULTIBOOT_MEMORY_AVAILABLE) add_frame_node(mmmt); } } void init_memory(multiboot_info_t *mbd, uint32_t magic) { for (uint16_t i = 0; i < 0x300; i++) page_directory[i] = 0x02; init_page_table(page_table_default, 0); page_directory[0] = ((uint32_t)page_table_default - HEAP_END) | 0x03; init_multiboot(mbd, magic); init_frame_zones(); }