diff --git a/Makefile b/Makefile index 7e835d8..b79145d 100644 --- a/Makefile +++ b/Makefile @@ -53,8 +53,8 @@ run-iso: iso fast-run-iso: fast-iso qemu-system-i386 -cdrom build/$(NAME).iso -vga std -debug: iso - qemu-system-i386 -s -S build/$(NAME).iso -vga std +debug: fast-iso + qemu-system-i386 -cdrom build/$(NAME).iso -vga std -d int -M smm=off 2> logs clean: make -C libbozo clean diff --git a/headers/memory.h b/headers/memory.h index c9a9c61..a226771 100644 --- a/headers/memory.h +++ b/headers/memory.h @@ -55,7 +55,7 @@ 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); -void *alloc_pages(size_t size); +void *alloc_pages(size_t size, void **phys_addr); int free_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); diff --git a/headers/task.h b/headers/task.h index 8a25ff7..4ce9f9b 100644 --- a/headers/task.h +++ b/headers/task.h @@ -4,20 +4,27 @@ #include +extern struct task *current_task; + enum status { ZOMBIE, THREAD, RUN }; +enum owner { OWNER_KERNEL, OWNER_USER }; struct task { uint32_t *esp; uint32_t *esp0; - uint32_t *cr3; + uint32_t *cr3; // physical + uint32_t *heap; // virtual + uint32_t *eip; uint16_t pid; uint8_t status; + uint8_t owner_id; struct task *daddy; struct task *child; struct list **signals; - uint8_t owner_id; struct task *next; + struct task *prev; }; void scheduler(void); void switch_to_task(struct task *next_task); +void exec_fn(void (*fn)(void)); diff --git a/src/kernel.c b/src/kernel.c index 2795f04..95c8d22 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -10,7 +10,9 @@ #include "power.h" #include "shell.h" #include "string.h" +#include "task.h" #include "terminal.h" +#include "time.h" #include "vbe.h" #include @@ -28,6 +30,24 @@ #error "This tutorial needs to be compiled with a ix86-elf compiler" #endif +static void uwu(void) +{ + sleep(1000); + kprintf("uwu\n"); +} + +static void owo(void) +{ + sleep(1000); + kprintf("owo\n"); +} + +static void awa(void) +{ + sleep(1000); + kprintf("awa\n"); +} + void kernel_main(multiboot_info_t *mbd, uint32_t magic) { terminal_initialize(); @@ -41,5 +61,8 @@ void kernel_main(multiboot_info_t *mbd, uint32_t magic) /* "complex 8*unknown quantity -byte descriptor table. -- Troy " */ /* "Martin 03:50, 22 March 2009 (UTC)\n"); */ + exec_fn(uwu); + exec_fn(owo); + exec_fn(awa); shell_init(); } diff --git a/src/memory/page.c b/src/memory/page.c index 826acf2..e74321f 100644 --- a/src/memory/page.c +++ b/src/memory/page.c @@ -32,7 +32,7 @@ static int16_t find_next_block(size_t nb_pages, uint16_t *pd_index_ptr, return -1; } -void *alloc_pages(size_t size) +void *alloc_pages(size_t size, void **phys_addr) { const uint32_t nb_pages = CEIL(size, PAGE_SIZE); uint16_t pd_index; @@ -51,6 +51,8 @@ void *alloc_pages(size_t size) free_frame((void *)(page_table[j] & PAGE_MASK)); return NULL; } + if (phys_addr) + *phys_addr = frame; page_table[i] = ((uint32_t)frame & PAGE_MASK) | INIT_FLAGS; } memset((void *)GET_PAGE_ADDR(pd_index, index), 0, nb_pages * PAGE_SIZE); diff --git a/src/memory/virt/allocator.c b/src/memory/virt/allocator.c index 28f3255..146425b 100644 --- a/src/memory/virt/allocator.c +++ b/src/memory/virt/allocator.c @@ -48,7 +48,7 @@ static void new_block(Zone *zone, uint32_t zone_size) int new_vzone(block_type_t type, uint32_t size) { - void *heap = alloc_pages(size); + void *heap = alloc_pages(size, NULL); if (heap == NULL) { kprintf(KERN_ERR "error: alloc_pages failed\n"); return (-1); diff --git a/src/multitasking/scheduler.c b/src/multitasking/scheduler.c index 815f6bb..b72a529 100644 --- a/src/multitasking/scheduler.c +++ b/src/multitasking/scheduler.c @@ -1,10 +1,14 @@ +#include "kprintf.h" #include "task.h" struct task *current_task; void scheduler(void) { - struct task *it = current_task->next; + kprintf("camille mon bebou\n"); + if (!current_task) + return; + struct task *it = current_task; while (it->status != RUN) it = it->next; switch_to_task(it); diff --git a/src/multitasking/switch_to_task.s b/src/multitasking/switch_to_task.s index 6a426e2..cb59b7d 100644 --- a/src/multitasking/switch_to_task.s +++ b/src/multitasking/switch_to_task.s @@ -16,11 +16,11 @@ switch_to_task: // and + 1 to get the argument (next task) mov esi, [esp+(4+1)*4] mov [current_task], esi - - mov esp, [current_task] - mov eax, [current_task+4] - mov ebx, [current_task+8] - mov [TSS + 4], eax + + mov esp, [current_task] // esp + mov eax, [current_task+4] // esp0 + mov ebx, [current_task+8] // cr3 + mov [TSS+4], eax // tss.esp0 mov ecx, cr3 // if cr3 hasn't change, do nothing @@ -34,4 +34,4 @@ switch_to_task: pop ebp pop ebx - ret + ret // this will also change eip to the next task's instructions diff --git a/src/multitasking/task.c b/src/multitasking/task.c new file mode 100644 index 0000000..371127e --- /dev/null +++ b/src/multitasking/task.c @@ -0,0 +1,45 @@ +#include "task.h" +#include "alloc.h" +#include "kpanic.h" +#include "memory.h" + +static void set_eip(void (*fn)(void), struct task *task) +{ + // TODO or not TODO +} + +static struct task *create_task(uint8_t owner_id) +{ + static uint32_t pid = 1; + struct task *new_task = vmalloc(sizeof(struct task)); + if (!new_task) + return NULL; + new_task->owner_id = owner_id; + new_task->pid = pid++; + new_task->heap = alloc_pages(4096, (void **)&new_task->cr3); + if (!new_task->heap) { + vfree(new_task); + return NULL; + } + return new_task; +} + +void exec_fn(void (*fn)(void)) +{ + struct task *new_task = create_task(OWNER_KERNEL); + if (!new_task) + kpanic("failed to create new task"); + new_task->status = RUN; + new_task->next = current_task; + new_task->prev = current_task->prev; + current_task->prev = new_task; + current_task = new_task; + set_eip(fn, new_task); +} + +/* + * Create task + * Allocate new pd => kmalloc(4096) + * Add pd address to the struct task + * + */