diff --git a/src/memory/memory.c b/src/memory/memory.c index b5d4bd0..cd371f0 100644 --- a/src/memory/memory.c +++ b/src/memory/memory.c @@ -21,19 +21,19 @@ static void lst_add_back(struct frame_zone **root, struct frame_zone *element) it->next = element; } + static void add_frame_node(multiboot_memory_map_t *mmmt) { - static uint32_t index; - uint32_t *pd = &boot_page_directory; + static uint32_t index = 0; /** * # = kernel code * - = blank */ - uint32_t start_addr = mmmt->addr; - uint32_t end_addr = mmmt->addr + mmmt->len; - uint32_t len = mmmt->len; + 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: @@ -60,53 +60,60 @@ static void add_frame_node(multiboot_memory_map_t *mmmt) } end_addr = ROUND_CEIL(start_addr + len, PAGE_SIZE); - pd[PDE_FRAME_ZONES] = + PD[PDE_FRAME_ZONES] = ((uint32_t)frame_zones_page_table - VIRT_OFFSET) | INIT_FLAGS; - frame_zones_page_table[index] = - ((uint32_t)start_addr & PAGE_MASK) | INIT_FLAGS; + /** We need to determine how many frames are available + to save how many frame the blocks contain etc we need some meta data + 1 struct frame_zone and a frame_table, the size of the frame_table is 1 bit per frame + the frame_table is a uint8_t so 8 bit, so its size must be CEIL(max_frames, 8) + But we don't have max_frames. + We can determine max_frame = (block_len - sizeof(struct frame_zone)) / (PAGE_SIZE + 1 / 8) (1 / 8 because size is in byte but we only need one bit) + Because we don't use float we can't have 1 / 8 + So we will multiplicate every members of this equation by 8 to have only complet number + So... max_frame = (block_len - sizeof(struct frame_zone)) * 8 / (PAGE_SIZE * 8 + 1) + */ + const uint32_t nb_frame = (len - sizeof(struct frame_zone)) * 8 / (PAGE_SIZE * 8 + 1); + + const uint32_t frame_table_size = CEIL(nb_frame, (sizeof(uint8_t) * 8)); + uint32_t page_needed = CEIL(frame_table_size + sizeof(struct frame_zone), PAGE_SIZE); + uint32_t i = 0; + for (; i < page_needed; i++) + frame_zones_page_table[index + i] = (((uint32_t)start_addr + i * PAGE_SIZE) & PAGE_MASK) | INIT_FLAGS; + struct frame_zone *current = - (struct frame_zone *)PTE2VA(PDE_FRAME_ZONES, index++); + (struct frame_zone *)PTE2VA(PDE_FRAME_ZONES, index); - current->frame_table = (uint8_t *)current + sizeof(struct frame_zone); + current->frame_table = (uint8_t*) ((uint32_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; + current->addr = (void*)(uint32_t)start_addr + page_needed * PAGE_SIZE; - memset(current->frame_table, 0, - nb_frame * sizeof(*current->frame_table)); + bzero(current->frame_table, frame_table_size); - 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; + index += i; 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; + for(uint32_t i = 0; i < mmap_length; + i += sizeof(multiboot_memory_map_t)) + { + multiboot_memory_map_t* mmmt = + (multiboot_memory_map_t*) ((uint32_t)mmap_addr + i); + if (mmmt->type == MULTIBOOT_MEMORY_AVAILABLE) add_frame_node(mmmt); } } -void init_memory(multiboot_info_t *mbd, uint32_t magic) +void init_memory() { - init_multiboot(mbd, magic); init_frame_zones(); // initialize all the PTs for (uint16_t i = KERNEL_PT_START; i < KERNEL_PT_END; i++) { @@ -115,7 +122,6 @@ void init_memory(multiboot_info_t *mbd, uint32_t magic) kpanic("Couldn't initialize kernel PTs\n"); PD[i] = frame | RW; } - PD[1023] = ((uint32_t)&boot_page_directory - VIRT_OFFSET) | INIT_FLAGS; // kalash kalash kalash sur la mélodie chez nous pas de félonie ça vient // de Sevran les R }