From fe32c209fe14c24dc99a9cbdffa55749fa759c21 Mon Sep 17 00:00:00 2001 From: Ivan Gualandri Date: Mon, 21 Oct 2024 00:45:53 +0100 Subject: [PATCH] Working on elf task creation (cont.) --- src/include/kernel/loaders/elf.h | 2 + src/include/kernel/scheduling/task.h | 11 +++++- src/kernel/loaders/elf.c | 15 +++++++- src/kernel/main.c | 5 ++- src/kernel/scheduling/task.c | 56 +++++++++++++++++++++------- 5 files changed, 71 insertions(+), 18 deletions(-) diff --git a/src/include/kernel/loaders/elf.h b/src/include/kernel/loaders/elf.h index cfe43c8..50806ba 100644 --- a/src/include/kernel/loaders/elf.h +++ b/src/include/kernel/loaders/elf.h @@ -88,4 +88,6 @@ bool parse_section_header(Elf64_Ehdr *elf_start, uint64_t size, executable_loade Elf64_Half loop_phdrs(Elf64_Ehdr* e_phdr, Elf64_Half phdr_entries); Elf64_Phdr *read_phdr(Elf64_Ehdr* e_hdr, Elf64_Half phdr_entry_number); + +uint64_t elf_flags_to_memory_flags(Elf64_Word flags); #endif diff --git a/src/include/kernel/scheduling/task.h b/src/include/kernel/scheduling/task.h index 5482456..9e546f6 100644 --- a/src/include/kernel/scheduling/task.h +++ b/src/include/kernel/scheduling/task.h @@ -27,14 +27,21 @@ struct task_t { extern size_t next_task_id; -task_t* create_task( char *name, void (*_entry_point)(void *), void *args, bool is_supervisor ); +task_t* create_task( char *name, bool is_supervisor ); +task_t *create_task_from_func(char *name, void (*_entry_point)(void *), void *args, bool is_supervisor); +task_t *create_task_from_elf(char *name, void *args, Elf64_Ehdr *elf_header); + task_t* get_task( size_t task_id ); bool add_thread_to_task_by_id( size_t task_id, thread_t* thread ); bool add_thread_to_task( task_t* task, thread_t* thread ); + bool delete_thread_from_task( size_t thread_id, task_t *task ); -void prepare_virtual_memory_environment( task_t* task ); + +void prepare_virtual_memory_environment(task_t* task); + void print_thread_list( size_t task_id ); + bool remove_thread_from_task(size_t thread_id, task_t *task); #endif diff --git a/src/kernel/loaders/elf.c b/src/kernel/loaders/elf.c index dbd9554..ea7e623 100644 --- a/src/kernel/loaders/elf.c +++ b/src/kernel/loaders/elf.c @@ -21,10 +21,13 @@ void load_elf(uintptr_t elf_start, uint64_t size) { if (result > 0) { pretty_logf(Verbose, " Number of PT_LOAD entries: %d", result); Elf64_Phdr *cur_phdr = read_phdr(elf_header, 0); - pretty_logf(Verbose, "\t[cur_phdr]: Type: 0x%x, Flags: 0x%x - Vaddr: 0x%x - aligned: 0x%x - p_align: 0x%x - p_memsz: 0%x ", cur_phdr->p_type, cur_phdr->p_flags, cur_phdr->p_vaddr, align_value_to_page(cur_phdr->p_vaddr), cur_phdr->p_align, cur_phdr->p_memsz); + pretty_logf(Verbose, "\t[cur_phdr]: Type: 0x%x, Flags: 0x%x - Vaddr: 0x%x - aligned: 0x%x - p_align: 0x%x - p_memsz: 0%x - p_offset: 0x%x", cur_phdr->p_type, cur_phdr->p_flags, cur_phdr->p_vaddr, align_value_to_page(cur_phdr->p_vaddr), cur_phdr->p_align, cur_phdr->p_memsz, cur_phdr->p_offset); + cur_phdr = read_phdr(elf_header, 1); + pretty_logf(Verbose, "\t[cur_phdr]: Type: 0x%x, Flags: 0x%x - Vaddr: 0x%x - aligned: 0x%x - p_align: 0x%x - p_memsz: 0%x - p_offset: 0x%x", cur_phdr->p_type, cur_phdr->p_flags, cur_phdr->p_vaddr, align_value_to_page(cur_phdr->p_vaddr), cur_phdr->p_align, cur_phdr->p_memsz, cur_phdr->p_offset); // Now is time to create a atask } } + //while(1); } Elf64_Half loop_phdrs(Elf64_Ehdr* e_hdr, Elf64_Half phdr_entries) { @@ -103,3 +106,13 @@ bool parse_section_header(Elf64_Ehdr *elf_start, uint64_t size, executable_loade } return false; } + +uint64_t elf_flags_to_memory_flags(Elf64_Word flags) { + // Elf flags: + // 1 = Read + // 2 = Write + // 4 = Execute + // They can be mixed. + uint64_t flags_to_return = (flags & 0b10); + return flags_to_return; +} diff --git a/src/kernel/main.c b/src/kernel/main.c index de945bc..b29641c 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -264,9 +264,10 @@ void kernel_start(unsigned long addr, unsigned long magic){ #endif init_scheduler(); char a = 'a'; - task_t* idle_task = create_task("idle", idle, &a, true); + task_t* idle_task = create_task_from_func("idle", idle, &a, true); idle_thread = idle_task->threads; - task_t* userspace_task = create_task("userspace_idle", NULL, &a, false); + task_t* userspace_task = create_task_from_func("userspace_idle", NULL, &a, false); + task_t* elf_task = create_task_from_elf("elf_idle", NULL, (Elf64_Ehdr *) (uintptr_t) hhdm_get_variable(elf_module_start_phys)); //create_thread("ledi", noop2, &c, eldi_task); //create_task("sleeper", noop3, &d); //execute_runtime_tests(); diff --git a/src/kernel/scheduling/task.c b/src/kernel/scheduling/task.c index 591d42d..de0785c 100644 --- a/src/kernel/scheduling/task.c +++ b/src/kernel/scheduling/task.c @@ -1,34 +1,67 @@ +#include #include -#include -#include +#include #include -#include #include #include -#include +#include +#include +#include +#include #include #include -#include extern uint64_t p4_table[]; extern uint64_t p3_table[]; extern uint64_t p3_table_hh[]; -task_t* create_task(char *name, void (*_entry_point)(void *), void *args, bool is_supervisor) { +task_t* create_task(char *name, bool is_supervisor) { //disable interrupts while creating a task - asm("cli"); task_t* new_task = (task_t*) kmalloc(sizeof(task_t)); strcpy(new_task->task_name, name); new_task->parent = NULL; new_task->task_id = next_task_id++; pretty_logf(Verbose, "Task created with name: %s - Task id: %d", new_task->task_name, new_task->task_id); - prepare_virtual_memory_environment(new_task); + //prepare_virtual_memory_environment(new_task); if ( is_supervisor ){ vmm_init(VMM_LEVEL_SUPERVISOR, &(new_task->vmm_data)); } else { vmm_init(VMM_LEVEL_USER, &(new_task->vmm_data)); } - if( is_supervisor) { + //scheduler_add_task(new_task); + //re-enable interrupts + return new_task; +} + +task_t *create_task_from_elf(char *name, void *args, Elf64_Ehdr *elf_header){ + asm("cli"); + // I will not create a task from elf if is_supervisor is true. + task_t* new_task = create_task(name, false); + prepare_virtual_memory_environment(new_task); + if(elf_header != NULL) { + //Here i will put the code to handle the case where an Elf is passed. + Elf64_Half phdr_entries = elf_header->e_phnum; + Elf64_Half phdr_entsize = elf_header->e_phentsize; + pretty_logf(Verbose, " Number of PHDR entries: 0x%x", phdr_entries); + pretty_logf(Verbose, " PHDR Entry Size: 0x%x", phdr_entsize ); + pretty_logf(Verbose, " ELF Entry point: 0x%x", elf_header->e_entry); + /*for ( int i = 0; i < phdr_entries; i++) { + // I need first to compute the number of pages required for each phdr + // clear all the memory not used + // compute the entries for each page and insert them into the page tables. + }*/ + } + // Create a new thread + scheduler_add_task(new_task); + asm("sti"); + return new_task; +} + +task_t *create_task_from_func(char *name, void (*_entry_point)(void *), void *args, bool is_supervisor) { + asm("cli"); + task_t* new_task = create_task(name, is_supervisor); + prepare_virtual_memory_environment(new_task); + if( is_supervisor) { pretty_logf(Verbose, "creating new supervisor thread: %s", name); thread_t* thread = create_thread(name, _entry_point, args, new_task, is_supervisor); new_task->threads = thread; @@ -38,9 +71,7 @@ task_t* create_task(char *name, void (*_entry_point)(void *), void *args, bool i new_task->threads = thread; } scheduler_add_task(new_task); - //re-enable interrupts asm("sti"); - return new_task; } void prepare_virtual_memory_environment(task_t* task) { @@ -51,8 +82,7 @@ void prepare_virtual_memory_environment(task_t* task) { //pretty_logf(Verbose, "vm_root_page_table address: %x", task->vm_root_page_table); //identity_map_phys_address(task->vm_root_page_table, 0); // I will get the page frame first, then get virtual address to map it to with vmm_alloc, and then do the mapping on the virtual address. - // Technically the vmm_alloc is not needed, since i have the direct memory map already accessible, so i just need to access it through the direct map. - + // Technically the vmm_alloc is not needed, since i have the direct memory map already accessible, so i just need to access it through the direct m //void* vm_root_vaddress = vmm_alloc(PAGE_SIZE_IN_BYTES, VMM_FLAGS_ADDRESS_ONLY, NULL); void* vm_root_vaddress = hhdm_get_variable ((uintptr_t) task->vm_root_page_table); task->vmm_data.root_table_hhdm = (uintptr_t) vm_root_vaddress;