diff --git a/Makefile b/Makefile index 238bdc3..56d9528 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,7 @@ fast-run-iso: fast-iso qemu-system-i386 -cdrom build/$(NAME).iso -vga std debug: fast-iso - qemu-system-i386 -s -S -cdrom build/$(NAME).iso -vga std -D qemu.log -d in_asm,int -M smm=off + qemu-system-i386 -s -S -cdrom build/$(NAME).iso -vga std -d in_asm,int -M smm=off clean: make -C libbozo clean diff --git a/headers/memory.h b/headers/memory.h index f6e1d96..16c64c4 100644 --- a/headers/memory.h +++ b/headers/memory.h @@ -12,18 +12,31 @@ #define ACCESSED (1 << 4) #define INIT_FLAGS (PRESENT | RW | SUPERVISOR) #define PAGE_SIZE 4096 -#define PT_SIZE 1024 -#define PD_SIZE 1024 +#define PD ((uint32_t *)0xFFFFF000) +#define VIRT_PT_BASE 0xFFC00000 +#define VIRT_PD_BASE 0xFFFFF000 #define PAGE_MASK 0xFFFFF000 -#define HEAP_END 0xC0000000 -#define HEAP_START ((uint32_t)&_kernel_end - HEAP_END) +#define VIRT_OFFSET 0xC0000000 #define KERNEL_START ((uint32_t)&_kernel_start) -#define KERNEL_END ((uint32_t)&_kernel_end - HEAP_END) +#define KERNEL_END ((uint32_t)&_kernel_end - VIRT_OFFSET) #define KERNEL_PT_END 1020 #define KERNEL_PT_START 769 -#define GET_PAGE_ADDR(pd_index, pt_index) \ - ((((uint32_t)pd_index * 1024) + (uint32_t)pt_index) * 4096) +#define PDE_VBE 1021 +#define PDE_FRAME_ZONES 1022 +#define PDE_MULTIBOOT 1023 + +#define PTE2VA(pd_index, pt_index) \ + ((uint32_t *)((((uint32_t)pd_index * 1024) + (uint32_t)pt_index) * \ + 4096)) +static inline uint32_t *VA2PTE(uint32_t va) +{ + uint32_t pde = va >> 22; + uint32_t pte = (va >> 12) & 0x3FF; + + uint32_t *pt = (uint32_t *)(VIRT_PT_BASE + (pde * 0x1000)); + return &pt[pte]; +} #define GET_FRAME(frame_table, i) (frame_table[i / 8] & (1 << (i % 8))) #define SET_FRAME(frame_table, i, used) \ @@ -47,23 +60,14 @@ extern uint32_t _kernel_end; extern uint32_t _kernel_start; extern uint32_t boot_page_directory; extern uint32_t boot_page_table1; -extern uint32_t *kernel_pd; -extern uint32_t *current_pd; -extern uint32_t page_table_default[1024]; -extern uint32_t mem_size; extern multiboot_memory_map_t *mmap_addr; extern multiboot_uint32_t mmap_length; extern struct frame_zone *head; -uint32_t *virt_to_phys(uint32_t *virt_addr); void init_memory(multiboot_info_t *mbd, uint32_t magic); void *alloc_frame(void); int free_frame(void *frame_ptr); -int8_t add_single_page(void *frame); -void *kalloc_pages(size_t size, void **phys_addr); +void *kalloc_pages(size_t nb_pages); void *valloc_pages(size_t size, void **phys_addr); int kfree_pages(void *page_ptr, size_t size); int vfree_pages(void *page_ptr, size_t size); -void init_page_table(uint32_t page_table[1024], uint16_t start); -int16_t add_page_table(uint16_t pd_index, uint16_t pt_start); -void switch_pd(uint32_t *pd, uint32_t *cr3); diff --git a/src/memory/kern/allocator.c b/src/memory/kern/allocator.c index cfb905e..c58448d 100644 --- a/src/memory/kern/allocator.c +++ b/src/memory/kern/allocator.c @@ -49,7 +49,7 @@ static void new_block(Zone *zone, uint32_t zone_size) int new_kzone(block_type_t type, uint32_t size) { // assert(current_task->pid); - void *heap = kalloc_pages(size, NULL); + void *heap = kalloc_pages(size); if (heap == NULL) { kprintf(KERN_ERR "error: alloc_frame failed\n"); return (-1); diff --git a/src/memory/kern/page.c b/src/memory/kern/page.c index 63fdf7e..b7ec6c2 100644 --- a/src/memory/kern/page.c +++ b/src/memory/kern/page.c @@ -9,86 +9,51 @@ #include "string.h" #include "utils.h" -static int16_t find_next_block(size_t nb_pages, uint16_t *pd_index_ptr, - uint32_t **page_table_ptr) +static uint32_t *find_next_block(size_t nb_pages) { - - for (*pd_index_ptr = KERNEL_PT_START; *pd_index_ptr < KERNEL_PT_END; - (*pd_index_ptr)++) { - if (current_pd[(*pd_index_ptr)] == 0x02) { - if (add_page_table(*pd_index_ptr, KERNEL_PT_START) < 0) - return -2; - } - *page_table_ptr = - (uint32_t *)GET_PAGE_ADDR(KERNEL_PT_START, *pd_index_ptr); - for (uint16_t i = 0; i + nb_pages - 1 < PT_SIZE; i++) { - uint16_t j; - for (j = 0; (*page_table_ptr)[i + j] >> 12 == i + j && - j < nb_pages; - j++) - ; - if (j == nb_pages) - return i; - i += j; + uint32_t count = 0; + for (uint32_t *pte = PTE2VA(1023, 0); pte < PTE2VA(1023, 1023); pte++) { + if (!*pte) { + count = 0; + continue; } + count++; + if (count == nb_pages) + return pte - count; } - return -1; + return NULL; } -void *kalloc_pages(size_t size, void **phys_addr) +void *kalloc_pages(size_t nb_pages) { - const uint32_t nb_pages = CEIL(size, PAGE_SIZE); - uint16_t pd_index; - uint32_t *page_table; - const int16_t index = find_next_block(nb_pages, &pd_index, &page_table); - - if (index < 0) { - kprintf(KERN_CRIT "%d: Not enough pages (max: %d)\n", index, - PT_SIZE); - return NULL; - } - for (size_t i = index; i - (size_t)index < nb_pages; i++) { + uint32_t *start = find_next_block(nb_pages); + for (uint32_t i = 0; i < nb_pages; i++) { void *frame = alloc_frame(); if (!frame) { - for (size_t j = index; j < i; j++) - free_frame((void *)(page_table[j] & PAGE_MASK)); + for (uint32_t j = 0; j < i; j++) + free_frame((void *)(((uint32_t)(start + j)) & + PAGE_MASK)); return NULL; } - if (phys_addr) - *phys_addr = frame; - page_table[i] = ((uint32_t)frame & PAGE_MASK) | INIT_FLAGS; + assert(!((uint32_t)frame & PAGE_MASK)); + start[i] = (uint32_t)frame | INIT_FLAGS; } - return (void *)GET_PAGE_ADDR(pd_index, index); + uint32_t page_index = start - PTE2VA(1023, 0); + return PTE2VA(page_index / 1024, page_index % 1024); } -int kfree_pages(void *page_ptr, size_t size) +int kfree_pages(void *page_ptr, size_t nb_pages) { const uint32_t page_addr = (uint32_t)page_ptr; - const uint32_t nb_pages = CEIL(size, PAGE_SIZE); - const uint32_t page_index = page_addr / PAGE_SIZE; - const uint32_t pd_index = page_index / PD_SIZE; - const uint32_t pt_index = page_index % PD_SIZE; - - if ((uint32_t)pd_index < KERNEL_PT_START || pd_index > KERNEL_PT_END) { - kprintf(KERN_WARNING "Address out of range\n"); - return -1; - } else if (page_addr % PAGE_SIZE) { + if (page_addr % PAGE_SIZE) { kprintf(KERN_WARNING "Invalid address\n"); return -1; - } else if (pt_index + nb_pages > PT_SIZE) { - kprintf(KERN_WARNING "Invalid number of frames\n"); - return -1; - } - uint32_t *page_table = - (uint32_t *)GET_PAGE_ADDR(KERNEL_PT_START, pd_index); - for (uint16_t i = pt_index; i < pt_index + nb_pages; i++) { - if (page_table[i] >> 12 == i) { - kprintf(KERN_WARNING "Page already free\n"); - return -2; - } - free_frame((void *)(page_table[i] & PAGE_MASK)); - page_table[i] = i << 12; } + for (uint32_t *pte = VA2PTE(page_addr); + pte < VA2PTE(page_addr) + nb_pages; pte++) { + free_frame((void *)(*pte & PAGE_MASK)); + *pte = 0; + } return 0; } diff --git a/src/memory/memory.c b/src/memory/memory.c index c9ac480..e206d66 100644 --- a/src/memory/memory.c +++ b/src/memory/memory.c @@ -1,22 +1,14 @@ #include "memory.h" +#include "kpanic.h" #include "string.h" #include "utils.h" #include -uint32_t *kernel_pd = &boot_page_directory; -uint32_t *current_pd; -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; -void switch_pd(uint32_t *pd, uint32_t *cr3) -{ - current_pd = pd; - asm volatile("mov %0, %%cr3" ::"r"(cr3)); -} - static void lst_add_back(struct frame_zone **root, struct frame_zone *element) { if (!*root) { @@ -38,9 +30,9 @@ static void add_frame_node(multiboot_memory_map_t *mmmt) * - = blank */ - uint64_t start_addr = mmmt->addr; - uint64_t end_addr = mmmt->addr + mmmt->len; - uint64_t len = mmmt->len; + uint32_t start_addr = mmmt->addr; + uint32_t end_addr = mmmt->addr + mmmt->len; + uint32_t len = mmmt->len; /** Kernel code cover all the block * this situation: @@ -67,13 +59,13 @@ static void add_frame_node(multiboot_memory_map_t *mmmt) } end_addr = ROUND_CEIL(start_addr + len, PAGE_SIZE); - init_page_table(frame_zones_page_table, 0); - kernel_pd[1022] = ((uint32_t)frame_zones_page_table - HEAP_END) | 0x03; + 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; struct frame_zone *current = - (struct frame_zone *)GET_PAGE_ADDR(1022, index++); + (struct frame_zone *)PTE2VA(PDE_FRAME_ZONES, index++); current->frame_table = (uint8_t *)current + sizeof(struct frame_zone); @@ -96,7 +88,7 @@ static void add_frame_node(multiboot_memory_map_t *mmmt) 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; + current->addr = (void *)(start_addr + i * PAGE_SIZE); index += i - 1; lst_add_back(&head, current); } @@ -113,11 +105,16 @@ static void init_frame_zones(void) void init_memory(multiboot_info_t *mbd, uint32_t magic) { - for (uint16_t i = KERNEL_PT_START; i < 1020; i++) - kernel_pd[i] = 0x02; - init_page_table(page_table_default, 0); - kernel_pd[1020] = ((uint32_t)page_table_default - HEAP_END) | 0x03; - current_pd = kernel_pd; init_multiboot(mbd, magic); init_frame_zones(); + // initialize all the PTs + for (uint16_t i = KERNEL_PT_START; i < KERNEL_PT_END; i++) { + uint32_t frame = (uint32_t)alloc_frame(); + if (!frame) + 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 } diff --git a/src/memory/page_table.c b/src/memory/page_table.c deleted file mode 100644 index 6e37292..0000000 --- a/src/memory/page_table.c +++ /dev/null @@ -1,19 +0,0 @@ -#include "memory.h" - -void init_page_table(uint32_t page_table[1024], uint16_t start) -{ - for (uint16_t i = start; i < 1024; i++) - page_table[i] = (i << 12) | 0x03; -} - -int16_t add_page_table(uint16_t pd_index, uint16_t pt_start) -{ - void *frame = alloc_frame(); - if (!frame) - return -1; - page_table_default[pd_index] = ((uint32_t)frame & PAGE_MASK) | 0x03; - uint32_t *page_table = (uint32_t *)GET_PAGE_ADDR(pt_start, pd_index); - init_page_table(page_table, 0); - kernel_pd[pd_index] = ((uint32_t)frame & PAGE_MASK) | 0x03; - return 0; -} diff --git a/src/memory/virt/page.c b/src/memory/virt/page.c index 459b3dd..a0d17cf 100644 --- a/src/memory/virt/page.c +++ b/src/memory/virt/page.c @@ -13,12 +13,12 @@ static int16_t find_next_block(size_t nb_pages, uint16_t *pd_index_ptr, uint32_t **page_table_ptr) { for (*pd_index_ptr = 2; *pd_index_ptr < 768; (*pd_index_ptr)++) { - if (current_pd[(*pd_index_ptr)] == 0x02) { - if (add_page_table(*pd_index_ptr, 1) < 0) - return -2; - } - *page_table_ptr = (uint32_t *)GET_PAGE_ADDR(1, *pd_index_ptr); - for (uint16_t i = 0; i + nb_pages - 1 < PT_SIZE; i++) { + // if (current_pd[(*pd_index_ptr)] == 0x02) { + // if (add_page_table(*pd_index_ptr, 1) < 0) + // return -2; + // } + *page_table_ptr = (uint32_t *)PTE2VA(1, *pd_index_ptr); + for (uint16_t i = 0; i + nb_pages - 1 < 1024; i++) { uint16_t j; for (j = 0; (*page_table_ptr)[i + j] >> 12 == i + j && j < nb_pages; @@ -41,7 +41,7 @@ void *valloc_pages(size_t size, void **phys_addr) if (index < 0) { kprintf(KERN_CRIT "%d: Not enough pages (max: %d)\n", index, - PT_SIZE); + 1024); return NULL; } for (size_t i = index; i - (size_t)index < nb_pages; i++) { @@ -55,7 +55,7 @@ void *valloc_pages(size_t size, void **phys_addr) *phys_addr = frame; page_table[i] = ((uint32_t)frame & PAGE_MASK) | INIT_FLAGS; } - return (void *)GET_PAGE_ADDR(pd_index, index); + return (void *)PTE2VA(pd_index, index); } int vfree_pages(void *page_ptr, size_t size) @@ -63,8 +63,8 @@ int vfree_pages(void *page_ptr, size_t size) const uint32_t page_addr = (uint32_t)page_ptr; const uint32_t nb_pages = CEIL(size, PAGE_SIZE); const uint32_t page_index = page_addr / PAGE_SIZE; - const uint32_t pd_index = page_index / PD_SIZE; - const uint32_t pt_index = page_index % PD_SIZE; + const uint32_t pd_index = page_index / 1024; + const uint32_t pt_index = page_index % 1024; if ((uint32_t)pd_index > 0x300) { kprintf(KERN_WARNING "Address out of range\n"); @@ -72,11 +72,11 @@ int vfree_pages(void *page_ptr, size_t size) } else if (page_addr % PAGE_SIZE) { kprintf(KERN_WARNING "Invalid address\n"); return -1; - } else if (pt_index + nb_pages > PT_SIZE) { + } else if (pt_index + nb_pages > 1024) { kprintf(KERN_WARNING "Invalid number of frames\n"); return -1; } - uint32_t *page_table = (uint32_t *)GET_PAGE_ADDR(1, pd_index); + uint32_t *page_table = (uint32_t *)PTE2VA(1, pd_index); for (uint16_t i = pt_index; i < pt_index + nb_pages; i++) { if (page_table[i] >> 12 == i) { kprintf(KERN_WARNING "Page already freed\n"); diff --git a/src/multiboot.c b/src/multiboot.c index 32fff32..60945ce 100644 --- a/src/multiboot.c +++ b/src/multiboot.c @@ -1,8 +1,6 @@ #include #include -#include "commands.h" -#include "debug.h" #include "kpanic.h" #include "memory.h" #include "multiboot.h" @@ -22,9 +20,10 @@ static void init_mmap(multiboot_info_t *mbd_virt, size_t *pt_index) multiboot_page_table[i + *pt_index] = ((mbd_virt->mmap_addr + i * PAGE_SIZE) & PAGE_MASK) | INIT_FLAGS; - mmap_addr = (multiboot_memory_map_t *)(GET_PAGE_ADDR(1023, *pt_index) + - (uint32_t)mbd_virt->mmap_addr % - PAGE_SIZE); + mmap_addr = + (multiboot_memory_map_t *)(PTE2VA(PDE_MULTIBOOT, *pt_index) + + (uint32_t)mbd_virt->mmap_addr % + PAGE_SIZE); mmap_length = mbd_virt->mmap_length / sizeof(multiboot_memory_map_t); *pt_index += i; } @@ -38,8 +37,8 @@ static void init_vbe(multiboot_info_t *mbd_virt) ((mbd_virt->framebuffer_addr + i * PAGE_SIZE) & PAGE_MASK) | INIT_FLAGS; } - kernel_pd[1021] = ((uint32_t)vbe_page_table - HEAP_END) | 0x03; - display.buff = (uint32_t *)GET_PAGE_ADDR(1021, 0) + + PD[PDE_VBE] = ((uint32_t)vbe_page_table - VIRT_OFFSET) | INIT_FLAGS; + display.buff = (uint32_t *)PTE2VA(PDE_VBE, 0) + (mbd_virt->framebuffer_addr % PAGE_SIZE); display.height = mbd_virt->framebuffer_height; display.width = mbd_virt->framebuffer_width; @@ -50,10 +49,10 @@ static void init_vbe(multiboot_info_t *mbd_virt) void init_multiboot(multiboot_info_t *mbd, uint32_t magic) { if (magic != MULTIBOOT_BOOTLOADER_MAGIC) - kpanic("invalid magic number! (git good skill issue)"); + kpanic("invalid magic number! (git gud skill issue)"); - init_page_table(multiboot_page_table, 0); - kernel_pd[1023] = ((uint32_t)multiboot_page_table - HEAP_END) | 0x03; + PD[PDE_MULTIBOOT] = + ((uint32_t)multiboot_page_table - VIRT_OFFSET) | INIT_FLAGS; size_t pt_index = CEIL( (uint32_t)mbd % PAGE_SIZE + sizeof(multiboot_info_t), PAGE_SIZE); @@ -62,7 +61,7 @@ void init_multiboot(multiboot_info_t *mbd, uint32_t magic) multiboot_page_table[i] = (((uint32_t)mbd + PAGE_SIZE * i) & PAGE_MASK) | INIT_FLAGS; multiboot_info_t *mbd_virt = - (multiboot_info_t *)(GET_PAGE_ADDR(1023, 0) + + (multiboot_info_t *)(PTE2VA(PDE_MULTIBOOT, 0) + (uint32_t)mbd % PAGE_SIZE); init_mmap(mbd_virt, &pt_index); init_vbe(mbd_virt); diff --git a/src/multitasking/fork.c b/src/multitasking/fork.c index e9d583c..17acd0f 100644 --- a/src/multitasking/fork.c +++ b/src/multitasking/fork.c @@ -10,7 +10,7 @@ static struct tcb *thread_clone(struct tcb *thread) if (!new_tcb) return NULL; new_tcb->tid = thread->tid; - new_tcb->esp0 = kalloc_pages(STACK_SIZE, NULL); + new_tcb->esp0 = kalloc_pages(STACK_SIZE); if (!new_tcb->esp0) { delete_thread(new_tcb); return NULL; @@ -31,10 +31,8 @@ pid_t fork(void) } new_pcb->daddy = current_pcb; lst_add_back(&new_pcb->children, new_node); - current_pd = new_pcb->cr3; // loop on threads clone thread_clone(current_pcb->thread_list->content); - current_pd = current_pcb->cr3; return new_pcb->pid; } diff --git a/src/multitasking/process.c b/src/multitasking/process.c index 775fda0..b47462d 100644 --- a/src/multitasking/process.c +++ b/src/multitasking/process.c @@ -16,12 +16,14 @@ struct pcb *create_process(uid_t uid) new_pcb->pid = pid++; new_pcb->tid = 1; - new_pcb->heap = kalloc_pages(4096, &new_pcb->cr3); + new_pcb->heap = kalloc_pages(4096); if (!new_pcb->heap) { kfree(new_pcb); return NULL; } - memcpy(new_pcb->heap, current_pd, 4096); + new_pcb->cr3 = + (void *)((uint32_t)VA2PTE((uint32_t)new_pcb->heap) & PAGE_MASK); + memcpy(new_pcb->heap, PD, 4096); new_pcb->daddy = NULL; new_pcb->children = NULL;