From 113cdcff2aef9eb383c439c73f98c6b14dd4b048 Mon Sep 17 00:00:00 2001 From: Ivan Gualandri Date: Mon, 30 Sep 2024 19:58:20 +0100 Subject: [PATCH 01/15] minor changes to loaders --- src/include/kernel/loaders/elf.h | 2 +- src/kernel/loaders/elf.c | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/include/kernel/loaders/elf.h b/src/include/kernel/loaders/elf.h index b334132..cfe43c8 100644 --- a/src/include/kernel/loaders/elf.h +++ b/src/include/kernel/loaders/elf.h @@ -87,5 +87,5 @@ void load_elf(uintptr_t elf_start, uint64_t size); bool parse_section_header(Elf64_Ehdr *elf_start, uint64_t size, executable_loader_type type); 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); #endif diff --git a/src/kernel/loaders/elf.c b/src/kernel/loaders/elf.c index a7bd60f..dbd9554 100644 --- a/src/kernel/loaders/elf.c +++ b/src/kernel/loaders/elf.c @@ -16,9 +16,13 @@ void load_elf(uintptr_t elf_start, uint64_t size) { 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); Elf64_Half result = loop_phdrs(elf_header, phdr_entries); 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); + // Now is time to create a atask } } } @@ -39,6 +43,14 @@ Elf64_Half loop_phdrs(Elf64_Ehdr* e_hdr, Elf64_Half phdr_entries) { return number_of_pt_loads; } +/** + * This function return the hhdm pointer of the physycal address provided + * + * + * @param e_hdr the elf header + * @param phdr_entry_number the entry number we want to read + * @return Elf64_Phdr * the selected P_hdr or NULL if not found. + */ Elf64_Phdr *read_phdr(Elf64_Ehdr* e_hdr, Elf64_Half phdr_entry_number) { Elf64_Half phdr_entries = e_hdr->e_phnum; From fe32c209fe14c24dc99a9cbdffa55749fa759c21 Mon Sep 17 00:00:00 2001 From: Ivan Gualandri Date: Mon, 21 Oct 2024 00:45:53 +0100 Subject: [PATCH 02/15] 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; From 449bdfbb8949af032a77ffa8c81af49d635bdd2c Mon Sep 17 00:00:00 2001 From: Ivan Gualandri Date: Wed, 23 Oct 2024 00:14:38 +0100 Subject: [PATCH 03/15] Fix includes --- src/include/kernel/scheduling/scheduler.h | 2 +- src/include/kernel/scheduling/task.h | 1 + src/kernel/scheduling/scheduler.c | 1 - src/kernel/scheduling/task.c | 10 ++++++++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/include/kernel/scheduling/scheduler.h b/src/include/kernel/scheduling/scheduler.h index 522c5c1..b3a0d01 100644 --- a/src/include/kernel/scheduling/scheduler.h +++ b/src/include/kernel/scheduling/scheduler.h @@ -1,10 +1,10 @@ #ifndef _SCHEDULER_H_ #define _SCHEDULER_H_ +#include #include #include #include -#include #define SCHEDULER_NUMBER_OF_TICKS 0x200 #define SCHEDULER_MAX_THREAD_NUMBER 0x10 diff --git a/src/include/kernel/scheduling/task.h b/src/include/kernel/scheduling/task.h index 9e546f6..ea0437b 100644 --- a/src/include/kernel/scheduling/task.h +++ b/src/include/kernel/scheduling/task.h @@ -1,6 +1,7 @@ #ifndef _TASK_H #define _TASK_H +#include #include #include #include diff --git a/src/kernel/scheduling/scheduler.c b/src/kernel/scheduling/scheduler.c index 0c0a956..5d50d9e 100644 --- a/src/kernel/scheduling/scheduler.c +++ b/src/kernel/scheduling/scheduler.c @@ -1,4 +1,3 @@ - #include #include #include diff --git a/src/kernel/scheduling/task.c b/src/kernel/scheduling/task.c index de0785c..18ac749 100644 --- a/src/kernel/scheduling/task.c +++ b/src/kernel/scheduling/task.c @@ -45,11 +45,17 @@ task_t *create_task_from_elf(char *name, void *args, Elf64_Ehdr *elf_header){ 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++) { + Elf64_Phdr *phdr_list = (Elf64_Phdr*) ((uintptr_t) elf_header + elf_header->e_phoff); + 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. - }*/ + Elf64_Phdr phdr = phdr_list[i]; + pretty_logf(Verbose, "\t[%d]: Type: 0x%x, Flags: 0x%x - Vaddr: 0x%x - aligned: 0x%x ", i, phdr.p_type, phdr.p_flags, phdr.p_vaddr, align_value_to_page(phdr.p_vaddr)); + pretty_logf(Verbose, "\t\t - FileSz: 0x%x, Memsz: 0x%x ", phdr.p_filesz, phdr.p_memsz); + Elf64_Half mem_pages = (Elf64_Half) get_number_of_pages_from_size(phdr.p_memsz); + Elf64_Half filesz_pages = (Elf64_Half) get_number_of_pages_from_size(phdr.p_filesz); + } } // Create a new thread scheduler_add_task(new_task); From 179601da4006fe1403a754395cc0fa2b999743e1 Mon Sep 17 00:00:00 2001 From: Ivan Gualandri Date: Thu, 24 Oct 2024 00:23:41 +0100 Subject: [PATCH 04/15] create_task_from_elf cont. --- src/kernel/loaders/elf.c | 8 ++++++++ src/kernel/scheduling/task.c | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/kernel/loaders/elf.c b/src/kernel/loaders/elf.c index ea7e623..bf6be89 100644 --- a/src/kernel/loaders/elf.c +++ b/src/kernel/loaders/elf.c @@ -107,7 +107,15 @@ bool parse_section_header(Elf64_Ehdr *elf_start, uint64_t size, executable_loade return false; } +/** + * This function given an elf p_hdr flag returns the architecture dependent vmm flags + * + * + * @param flags elf flags + * @return architecture dependant flags + */ uint64_t elf_flags_to_memory_flags(Elf64_Word flags) { + // This function will be movede into the arch dependant code // Elf flags: // 1 = Read // 2 = Write diff --git a/src/kernel/scheduling/task.c b/src/kernel/scheduling/task.c index 18ac749..ede3c31 100644 --- a/src/kernel/scheduling/task.c +++ b/src/kernel/scheduling/task.c @@ -51,10 +51,12 @@ task_t *create_task_from_elf(char *name, void *args, Elf64_Ehdr *elf_header){ // clear all the memory not used // compute the entries for each page and insert them into the page tables. Elf64_Phdr phdr = phdr_list[i]; + size_t vmm_hdr_flags = elf_flags_to_memory_flags(phdr.p_type); pretty_logf(Verbose, "\t[%d]: Type: 0x%x, Flags: 0x%x - Vaddr: 0x%x - aligned: 0x%x ", i, phdr.p_type, phdr.p_flags, phdr.p_vaddr, align_value_to_page(phdr.p_vaddr)); - pretty_logf(Verbose, "\t\t - FileSz: 0x%x, Memsz: 0x%x ", phdr.p_filesz, phdr.p_memsz); + pretty_logf(Verbose, "\t\t - FileSz: 0x%x, Memsz: 0x%x, vmm flags: 0x%x", phdr.p_filesz, phdr.p_memsz, vmm_hdr_flags); Elf64_Half mem_pages = (Elf64_Half) get_number_of_pages_from_size(phdr.p_memsz); Elf64_Half filesz_pages = (Elf64_Half) get_number_of_pages_from_size(phdr.p_filesz); + } } // Create a new thread From 71836a6c2567bc3e50cd6cf865bae1d76af7e4df Mon Sep 17 00:00:00 2001 From: Ivan Gualandri Date: Fri, 1 Nov 2024 00:24:47 +0000 Subject: [PATCH 05/15] continue work on create_task_from_elf --- src/include/kernel/mem/hh_direct_map.h | 1 + src/kernel/main.c | 2 +- src/kernel/mem/hh_direct_map.c | 11 +++++++++++ src/kernel/scheduling/task.c | 13 +++++++++++-- 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/include/kernel/mem/hh_direct_map.h b/src/include/kernel/mem/hh_direct_map.h index d2420f3..4e58db2 100644 --- a/src/include/kernel/mem/hh_direct_map.h +++ b/src/include/kernel/mem/hh_direct_map.h @@ -11,6 +11,7 @@ void early_map_physical_memory(uint64_t end_of_reserved_area); void *hhdm_get_variable ( uintptr_t phys_address ); +void *hhdm_get_phys_address(uintptr_t hhdm_address); void hhdm_map_physical_memory(); #endif diff --git a/src/kernel/main.c b/src/kernel/main.c index b29641c..6600407 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -118,7 +118,7 @@ void _init_basic_system(unsigned long addr){ tag_start = (struct multiboot_tag *) (addr + _HIGHER_HALF_KERNEL_MEM_START + 8); _mmap_parse(tagmmap); pmm_setup(addr, mbi_size); - kernel_settings.kernel_uptime = 0; + kernel_settings.kernel_uptime = 0; kernel_settings.paging.page_root_address = p4_table; uint64_t p4_table_phys_address = (uint64_t) p4_table - _HIGHER_HALF_KERNEL_MEM_START; kernel_settings.paging.hhdm_page_root_address = (uint64_t*) hhdm_get_variable( (uintptr_t) p4_table_phys_address); diff --git a/src/kernel/mem/hh_direct_map.c b/src/kernel/mem/hh_direct_map.c index 36c5158..355f4c8 100644 --- a/src/kernel/mem/hh_direct_map.c +++ b/src/kernel/mem/hh_direct_map.c @@ -28,6 +28,17 @@ void *hhdm_get_variable ( uintptr_t phys_address ) { return NULL; } +/** + * This is an helper function return the physical address given a hhdm one + * + * + * @return phys_address the physical address we want to retrieve + * @param hhdm_address of the physical address or NULL in case of error + */ +void *hhdm_get_phys_address(uintptr_t hhdm_address) { + return (void *)(hhdm_address - higherHalfDirectMapBase); +} + void hhdm_map_physical_memory() { // This function should be called only once, and the hhdm shouldn't change during the kernel uptime diff --git a/src/kernel/scheduling/task.c b/src/kernel/scheduling/task.c index ede3c31..4d5224b 100644 --- a/src/kernel/scheduling/task.c +++ b/src/kernel/scheduling/task.c @@ -53,10 +53,19 @@ task_t *create_task_from_elf(char *name, void *args, Elf64_Ehdr *elf_header){ Elf64_Phdr phdr = phdr_list[i]; size_t vmm_hdr_flags = elf_flags_to_memory_flags(phdr.p_type); pretty_logf(Verbose, "\t[%d]: Type: 0x%x, Flags: 0x%x - Vaddr: 0x%x - aligned: 0x%x ", i, phdr.p_type, phdr.p_flags, phdr.p_vaddr, align_value_to_page(phdr.p_vaddr)); - pretty_logf(Verbose, "\t\t - FileSz: 0x%x, Memsz: 0x%x, vmm flags: 0x%x", phdr.p_filesz, phdr.p_memsz, vmm_hdr_flags); + pretty_logf(Verbose, "\t\t - FileSz: 0x%x, Memsz: 0x%x, vmm flags: 0x%x - p_align: 0x%x", phdr.p_filesz, phdr.p_memsz, vmm_hdr_flags, phdr.p_align); Elf64_Half mem_pages = (Elf64_Half) get_number_of_pages_from_size(phdr.p_memsz); Elf64_Half filesz_pages = (Elf64_Half) get_number_of_pages_from_size(phdr.p_filesz); - + uint64_t offset_address = elf_header + phdr.p_offset; + uint64_t vaddr_address = align_value_to_page(phdr.p_vaddr); + for (int i = 0; i < mem_pages; i++) { + pretty_logf(Verbose, "Mapping: offset: 0x%x in vaddr: 0x%x", hhdm_get_phys_address(offset_address), vaddr_address); + map_phys_to_virt_addr_hh(hhdm_get_phys_address(offset_address), vaddr_address, vmm_hdr_flags, new_task->vmm_data.root_table_hhdm); + //I need a mem copy. I need to fopy the content of elf_header + phdr.p_offset into phdr.p_vaddr + offset_address += phdr.p_align; + vaddr_address += phdr.p_align; + //I need to allocate memory and map it into the new memory space, + } } } // Create a new thread From f1804e578a2bd97229039df40e689d8893540964 Mon Sep 17 00:00:00 2001 From: Ivan Gualandri Date: Sat, 9 Nov 2024 13:21:45 +0000 Subject: [PATCH 06/15] Habemus ELF (even if very limited and still drafty) --- Makefile | 1 + src/include/kernel/scheduling/thread.h | 2 +- src/kernel/arch/x86_64/mem/vmm_mapping.c | 6 +++--- src/kernel/loaders/elf.c | 7 ++----- src/kernel/main.c | 4 ++-- src/kernel/scheduling/task.c | 21 ++++++++++++--------- src/kernel/scheduling/thread.c | 13 ++++++++++--- 7 files changed, 31 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index 555fb50..ebb8097 100644 --- a/Makefile +++ b/Makefile @@ -67,6 +67,7 @@ $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME): $(BUILD_FOLDER)/kernel.bin grub.cfg cp $(BUILD_FOLDER)/kernel.bin $(BUILD_FOLDER)/isofiles/boot cp $(BUILD_FOLDER)/kernel.map $(BUILD_FOLDER)/isofiles/boot cp example.elf $(BUILD_FOLDER)/isofiles + cp example_syscall.elf $(BUILD_FOLDER)/isofiles grub-mkrescue -o $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME) $(BUILD_FOLDER)/isofiles $(BUILD_FOLDER)/%.o: src/%.s diff --git a/src/include/kernel/scheduling/thread.h b/src/include/kernel/scheduling/thread.h index fbe782c..b906e5d 100644 --- a/src/include/kernel/scheduling/thread.h +++ b/src/include/kernel/scheduling/thread.h @@ -42,7 +42,7 @@ struct thread_t { extern size_t next_thread_id; -thread_t* create_thread(char* thread_name, void (*_entry_point)(void *) , void* arg, struct task_t* parent_task, bool is_supervisor); +thread_t* create_thread(char* thread_name, void (*_entry_point)(void *) , void* arg, struct task_t* parent_task, bool is_supervisor, bool is_elf); void thread_execution_wrapper( void (*)(void *), void*); void thread_suicide_trap(); void thread_sleep(size_t millis); diff --git a/src/kernel/arch/x86_64/mem/vmm_mapping.c b/src/kernel/arch/x86_64/mem/vmm_mapping.c index 2be11f8..c8a0bf5 100644 --- a/src/kernel/arch/x86_64/mem/vmm_mapping.c +++ b/src/kernel/arch/x86_64/mem/vmm_mapping.c @@ -47,7 +47,7 @@ void *map_phys_to_virt_addr_hh(void* physical_address, void* address, size_t fla clean_new_table(new_table_hhdm); pdpr_root = new_table_hhdm; } else { - pretty_log(Verbose, "No need to allocate pml4"); + //pretty_log(Verbose, "No need to allocate pml4"); pdpr_root = (uint64_t *) hhdm_get_variable((uintptr_t) pml4_root[pml4_e] & VM_PAGE_TABLE_BASE_ADDRESS_MASK); } @@ -59,7 +59,7 @@ void *map_phys_to_virt_addr_hh(void* physical_address, void* address, size_t fla clean_new_table(new_table_hhdm); pd_root = new_table_hhdm; } else { - pretty_log(Verbose, "No need to allocate pdpr"); + //pretty_log(Verbose, "No need to allocate pdpr"); pd_root = (uint64_t *) hhdm_get_variable((uintptr_t) pdpr_root[pdpr_e] & VM_PAGE_TABLE_BASE_ADDRESS_MASK); } @@ -72,7 +72,7 @@ void *map_phys_to_virt_addr_hh(void* physical_address, void* address, size_t fla clean_new_table(new_table_hhdm); pt_table = new_table_hhdm; } else { - pretty_log(Verbose, "No need to allocate pd"); + //pretty_log(Verbose, "No need to allocate pd"); pt_table = (uint64_t *) hhdm_get_variable((uintptr_t) pd_root[pd_e] & VM_PAGE_TABLE_BASE_ADDRESS_MASK); } diff --git a/src/kernel/loaders/elf.c b/src/kernel/loaders/elf.c index bf6be89..ed4a2ad 100644 --- a/src/kernel/loaders/elf.c +++ b/src/kernel/loaders/elf.c @@ -24,10 +24,8 @@ void load_elf(uintptr_t elf_start, uint64_t size) { 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) { @@ -35,7 +33,7 @@ Elf64_Half loop_phdrs(Elf64_Ehdr* e_hdr, Elf64_Half phdr_entries) { Elf64_Half number_of_pt_loads = 0; for (size_t i = 0; i < phdr_entries; i++) { Elf64_Phdr phdr = phdr_list[i]; - pretty_logf(Verbose, "\t[%d]: Type: 0x%x, Flags: 0x%x - Vaddr: 0x%x - aligned: 0x%x ", i, phdr.p_type, phdr.p_flags, phdr.p_vaddr, align_value_to_page(phdr.p_vaddr)); + pretty_logf(Verbose, "\t[%d]: Type: 0x%x, Flags: 0x%x - Vaddr: 0x%x - aligned: 0x%x - offset: 0x%x ", i, phdr.p_type, phdr.p_flags, phdr.p_vaddr, align_value_to_page(phdr.p_vaddr), phdr.p_offset); if ( is_address_aligned(phdr.p_vaddr, PAGE_SIZE_IN_BYTES) ) { pretty_log(Verbose, "\tThe address is aligned"); } else { @@ -47,7 +45,7 @@ Elf64_Half loop_phdrs(Elf64_Ehdr* e_hdr, Elf64_Half phdr_entries) { } /** - * This function return the hhdm pointer of the physycal address provided + * This function return the phdr entry at the pdhrd_entry_number provided. * * * @param e_hdr the elf header @@ -63,7 +61,6 @@ Elf64_Phdr *read_phdr(Elf64_Ehdr* e_hdr, Elf64_Half phdr_entry_number) { } return NULL; - } diff --git a/src/kernel/main.c b/src/kernel/main.c index 6600407..7d3717b 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -235,7 +235,7 @@ void kernel_start(unsigned long addr, unsigned long magic){ init_apic(); if (loaded_module != NULL) { if ( load_module_hh(loaded_module) ) { - pretty_log(Verbose, " The ELF module can be loaded succesfully" ); + pretty_logf(Verbose, " The ELF module can be loaded succesfully (Phys addr: 0x%x)", loaded_module->mod_start ); elf_module_start_phys = loaded_module->mod_start; } } @@ -266,7 +266,7 @@ void kernel_start(unsigned long addr, unsigned long magic){ char a = 'a'; task_t* idle_task = create_task_from_func("idle", idle, &a, true); idle_thread = idle_task->threads; - task_t* userspace_task = create_task_from_func("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); diff --git a/src/kernel/scheduling/task.c b/src/kernel/scheduling/task.c index 4d5224b..cc58ff8 100644 --- a/src/kernel/scheduling/task.c +++ b/src/kernel/scheduling/task.c @@ -53,20 +53,23 @@ task_t *create_task_from_elf(char *name, void *args, Elf64_Ehdr *elf_header){ Elf64_Phdr phdr = phdr_list[i]; size_t vmm_hdr_flags = elf_flags_to_memory_flags(phdr.p_type); pretty_logf(Verbose, "\t[%d]: Type: 0x%x, Flags: 0x%x - Vaddr: 0x%x - aligned: 0x%x ", i, phdr.p_type, phdr.p_flags, phdr.p_vaddr, align_value_to_page(phdr.p_vaddr)); - pretty_logf(Verbose, "\t\t - FileSz: 0x%x, Memsz: 0x%x, vmm flags: 0x%x - p_align: 0x%x", phdr.p_filesz, phdr.p_memsz, vmm_hdr_flags, phdr.p_align); + pretty_logf(Verbose, "\t\t - FileSz: 0x%x, Memsz: 0x%x, vmm flags: 0x%x - p_align: 0x%x - p_offset: 0x%x", phdr.p_filesz, phdr.p_memsz, vmm_hdr_flags, phdr.p_align, phdr.p_offset); Elf64_Half mem_pages = (Elf64_Half) get_number_of_pages_from_size(phdr.p_memsz); Elf64_Half filesz_pages = (Elf64_Half) get_number_of_pages_from_size(phdr.p_filesz); - uint64_t offset_address = elf_header + phdr.p_offset; + uint64_t offset_address = (uint64_t) ((uint64_t) elf_header + (uint64_t) phdr.p_offset); + pretty_logf(Verbose, "[%d]: offset_address: 0x%x (virtual: 0x%x) - elf_header: 0x%x", i, hhdm_get_phys_address(offset_address), offset_address, elf_header); uint64_t vaddr_address = align_value_to_page(phdr.p_vaddr); - for (int i = 0; i < mem_pages; i++) { - pretty_logf(Verbose, "Mapping: offset: 0x%x in vaddr: 0x%x", hhdm_get_phys_address(offset_address), vaddr_address); - map_phys_to_virt_addr_hh(hhdm_get_phys_address(offset_address), vaddr_address, vmm_hdr_flags, new_task->vmm_data.root_table_hhdm); + for (int j = 0; j < mem_pages; j++) { + pretty_logf(Verbose, "[%d]: Mapping: offset: 0x%x (virtual: 0x%x) in vaddr: 0x%x - elf_header: 0x%x", j, hhdm_get_phys_address(offset_address), offset_address, vaddr_address, hhdm_get_phys_address(elf_header)); + map_phys_to_virt_addr_hh(hhdm_get_phys_address(offset_address), vaddr_address, VMM_FLAGS_USER_LEVEL | vmm_hdr_flags | VMM_FLAGS_PRESENT, new_task->vmm_data.root_table_hhdm); //I need a mem copy. I need to fopy the content of elf_header + phdr.p_offset into phdr.p_vaddr - offset_address += phdr.p_align; - vaddr_address += phdr.p_align; + offset_address += (uint64_t) phdr.p_align; + vaddr_address += (uint64_t) phdr.p_align; //I need to allocate memory and map it into the new memory space, } } + thread_t* thread = create_thread(name, elf_header->e_entry, args, new_task, false, true); + pretty_logf(Verbose, "Thread created: id: %d - Entry Point: 0x%x - elf header entry point: 0x%x", thread->tid, thread->execution_frame->rip, elf_header->e_entry); } // Create a new thread scheduler_add_task(new_task); @@ -80,11 +83,11 @@ task_t *create_task_from_func(char *name, void (*_entry_point)(void *), void *ar 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); + thread_t* thread = create_thread(name, _entry_point, args, new_task, is_supervisor, false); new_task->threads = thread; } else { pretty_logf(Verbose, "creating new userspace thread %s", name); - thread_t* thread = create_thread(name, NULL, args, new_task, is_supervisor); + thread_t* thread = create_thread(name, NULL, args, new_task, is_supervisor, false); new_task->threads = thread; } scheduler_add_task(new_task); diff --git a/src/kernel/scheduling/thread.c b/src/kernel/scheduling/thread.c index a8f1415..b53d87c 100644 --- a/src/kernel/scheduling/thread.c +++ b/src/kernel/scheduling/thread.c @@ -14,7 +14,7 @@ unsigned char code_to_run[] = { 0xeb, 0xfe }; -thread_t* create_thread(char* thread_name, void (*_entry_point)(void *), void* arg, task_t* parent_task, bool is_supervisor) { +thread_t* create_thread(char* thread_name, void (*_entry_point)(void *), void* arg, task_t* parent_task, bool is_supervisor, bool is_elf) { // The first part is pretty trivial mostly bureaucray. Setting basic thread information like name, tid, parent... // Just like when registtering a new born child :D if ( parent_task == NULL) { @@ -30,7 +30,9 @@ thread_t* create_thread(char* thread_name, void (*_entry_point)(void *), void* a new_thread->next = NULL; new_thread->next_sibling = NULL; new_thread->ticks = 0; - pretty_logf(Verbose, "Creating thread with arg: %c - arg: %x - name: %s - rip: %x", (char) *((char*) arg), arg, thread_name, _entry_point); + if (arg != NULL) { + pretty_logf(Verbose, "Creating thread with arg: %c - arg: %x - name: %s - rip: %x", (char) *((char*) arg), arg, thread_name, _entry_point); + } //Here we create a new execution frame to be used when switching to a newly created task new_thread->execution_frame = kmalloc(sizeof(cpu_status_t)); @@ -39,7 +41,12 @@ thread_t* create_thread(char* thread_name, void (*_entry_point)(void *), void* a if (!is_supervisor) { // This piece of code is temporary, just to test a userspace task, it run just an infinite loop. pretty_logf(Verbose, "vmm_data address: 0x%x", &(parent_task->vmm_data)); - new_thread->execution_frame->rip = prepare_userspace_function(&(parent_task->vmm_data)); + if (is_elf ) { + pretty_logf(Verbose, "Preparing to launch an ELF. entry_pint = 0x%x", (uint64_t) _entry_point); + new_thread->execution_frame->rip = (uint64_t)_entry_point; + } else { + new_thread->execution_frame->rip = prepare_userspace_function(&(parent_task->vmm_data)); + } pretty_logf(Verbose, "using userspace function address: 0x%x", new_thread->execution_frame->rip); new_thread->execution_frame->rdi = 0; new_thread->execution_frame->rsi = 0; From 5f6b15423da0d6277308ce50efc47f0559e7e9ee Mon Sep 17 00:00:00 2001 From: Ivan Gualandri Date: Sat, 9 Nov 2024 13:26:14 +0000 Subject: [PATCH 07/15] Add new elf for testing --- example.elf | Bin 576 -> 0 bytes example_syscall.elf | Bin 0 -> 5200 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 example.elf create mode 100755 example_syscall.elf diff --git a/example.elf b/example.elf deleted file mode 100644 index fdd036bf39f595b2ab22c690f1d87da715bd17dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 576 zcmb<-^>JfjWMqH=Mg}_u1P><4z~F#jLfH-stPD&@qU13_c7ZS(n)U{$Blyt71GLos$UUJ4k`>66$G-d`QiXnVFFYo3y=n34k%v&N=pK1Z1yWa4F#Ex4AAZ0 zpA3}U2NFHo@cI*w(kn@=C}Gem&L}P^DoIQNvMO^SG=z_A7#=prL>7jR|FJ1y#uCFk cV1?+e0}7^AB<2?6q#ElLGvwsw7oeL50PRB^1poj5 diff --git a/example_syscall.elf b/example_syscall.elf new file mode 100755 index 0000000000000000000000000000000000000000..0f54d8635dd705029409a078bf13629e0ae1e6c2 GIT binary patch literal 5200 zcmeHL%Ss$U6us4Bvco6wD$Jx{ZPe2AwRDMMy$G2)Jshor+GF>6Y$NbQM3r zfA9y~x=Hc_`I4-XZ5GMB^=Lbl5yf@YFm-O7drm*jOfR}VzkKs5U<~XCU<=eL>M2Uk z0MU$90Q6u30-W0rD(%E|3oGl;cxieTA<_h$;{las4d#3nJ6Z-7Yn|ae_yl|cJ^`PA zPrxVO6YvT61bhNM0iS?Rz$b9`1itQ}_6xm@e?R;2>nUQO%%Pgyw{cBg&m7B^T86CF z+BbRR#R(rB4#iqrL2^)xL~<S(YnSh^v+}=YZBHHz6+$CwcmS61AvL27HQhJA9zJYIE^sp!nAx*QYN-N1r390CF z$r18CKwO=UB+n3Ksqw&8Qk+PL`yxBqPkG7neNoxvApcm{nrB%lj_qnV$VGkG_bwLD zN!ihFqlV4N?DN$7Iks)k!V(tbcSpzgSDc2crM}CNWy|>8TXeP0Z}49jKmDG~;rd@= z)8$D2&G@&Q<}q6G>L<_<(jN@Rxdxa*B%OIqVczg!oa!lKlzvb?^;PV&VOb6 IA8zsg1>QGY5dZ)H literal 0 HcmV?d00001 From 90204086765976d867e2d6f2b4b112382f9b4d76 Mon Sep 17 00:00:00 2001 From: Ivan Gualandri Date: Sat, 9 Nov 2024 13:29:17 +0000 Subject: [PATCH 08/15] Remove Makefile line --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index ebb8097..4af849b 100644 --- a/Makefile +++ b/Makefile @@ -66,7 +66,6 @@ $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME): $(BUILD_FOLDER)/kernel.bin grub.cfg cp grub.cfg $(BUILD_FOLDER)/isofiles/boot/grub cp $(BUILD_FOLDER)/kernel.bin $(BUILD_FOLDER)/isofiles/boot cp $(BUILD_FOLDER)/kernel.map $(BUILD_FOLDER)/isofiles/boot - cp example.elf $(BUILD_FOLDER)/isofiles cp example_syscall.elf $(BUILD_FOLDER)/isofiles grub-mkrescue -o $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME) $(BUILD_FOLDER)/isofiles From c973b6af6bf3800409e2e8fa0db84000141db639 Mon Sep 17 00:00:00 2001 From: Ivan Gualandri Date: Sat, 9 Nov 2024 13:42:51 +0000 Subject: [PATCH 09/15] update grub.cfg and fix compilation issues --- grub.cfg | 2 +- src/kernel/scheduling/task.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/grub.cfg b/grub.cfg index 41d4d64..d5e0cce 100644 --- a/grub.cfg +++ b/grub.cfg @@ -3,7 +3,7 @@ set default=0 menuentry "DreamOs64" { multiboot2 /boot/kernel.bin // Path to the loader executable - module2 /example.elf + module2 /example_syscall.elf boot // More modules may be added here in the form 'module ""' } diff --git a/src/kernel/scheduling/task.c b/src/kernel/scheduling/task.c index cc58ff8..4f9296c 100644 --- a/src/kernel/scheduling/task.c +++ b/src/kernel/scheduling/task.c @@ -10,6 +10,7 @@ #include #include #include +#include extern uint64_t p4_table[]; extern uint64_t p3_table[]; @@ -57,18 +58,17 @@ task_t *create_task_from_elf(char *name, void *args, Elf64_Ehdr *elf_header){ Elf64_Half mem_pages = (Elf64_Half) get_number_of_pages_from_size(phdr.p_memsz); Elf64_Half filesz_pages = (Elf64_Half) get_number_of_pages_from_size(phdr.p_filesz); uint64_t offset_address = (uint64_t) ((uint64_t) elf_header + (uint64_t) phdr.p_offset); - pretty_logf(Verbose, "[%d]: offset_address: 0x%x (virtual: 0x%x) - elf_header: 0x%x", i, hhdm_get_phys_address(offset_address), offset_address, elf_header); uint64_t vaddr_address = align_value_to_page(phdr.p_vaddr); for (int j = 0; j < mem_pages; j++) { - pretty_logf(Verbose, "[%d]: Mapping: offset: 0x%x (virtual: 0x%x) in vaddr: 0x%x - elf_header: 0x%x", j, hhdm_get_phys_address(offset_address), offset_address, vaddr_address, hhdm_get_phys_address(elf_header)); - map_phys_to_virt_addr_hh(hhdm_get_phys_address(offset_address), vaddr_address, VMM_FLAGS_USER_LEVEL | vmm_hdr_flags | VMM_FLAGS_PRESENT, new_task->vmm_data.root_table_hhdm); + pretty_logf(Verbose, "[%d]: Mapping: offset: 0x%x (virtual: 0x%x) in vaddr: 0x%x", j, hhdm_get_phys_address((uintptr_t) offset_address), offset_address, vaddr_address); + map_phys_to_virt_addr_hh(hhdm_get_phys_address(offset_address), (void *) vaddr_address, VMM_FLAGS_USER_LEVEL | vmm_hdr_flags | VMM_FLAGS_PRESENT, (uint64_t *) new_task->vmm_data.root_table_hhdm); //I need a mem copy. I need to fopy the content of elf_header + phdr.p_offset into phdr.p_vaddr offset_address += (uint64_t) phdr.p_align; vaddr_address += (uint64_t) phdr.p_align; //I need to allocate memory and map it into the new memory space, } } - thread_t* thread = create_thread(name, elf_header->e_entry, args, new_task, false, true); + thread_t* thread = create_thread(name, (void (*)(void *))elf_header->e_entry, args, new_task, false, true); pretty_logf(Verbose, "Thread created: id: %d - Entry Point: 0x%x - elf header entry point: 0x%x", thread->tid, thread->execution_frame->rip, elf_header->e_entry); } // Create a new thread From 58399e073a7daeb1c8cd6aa1951b71d58bebeab9 Mon Sep 17 00:00:00 2001 From: Ivan Gualandri Date: Wed, 13 Nov 2024 23:45:38 +0000 Subject: [PATCH 10/15] add source for example elf --- Makefile | 14 ++++++++++---- examples/example_syscall.s | 7 +++++++ 2 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 examples/example_syscall.s diff --git a/Makefile b/Makefile index 4af849b..1390949 100644 --- a/Makefile +++ b/Makefile @@ -42,9 +42,9 @@ ISO_IMAGE_FILENAME := $(IMAGE_BASE_NAME)-$(ARCH_PREFIX)-$(VERSION).iso default: build -.PHONY: default build run clean debug tests gdb todolist +.PHONY: default build run clean debug tests gdb todolist examples -build: $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME) +build: examples $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME) clean: -rm -rf $(BUILD_FOLDER) @@ -53,6 +53,12 @@ clean: run: $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME) $(QEMU_SYSTEM) -cdrom $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME) +examples: + echo "Building Examples" + mkdir -p $(BUILD_FOLDER)/examples + ${ASM_COMPILER} -g -felf64 -Fdwarf examples/example_syscall.s -o $(BUILD_FOLDER)/examples/example_syscall.o + $(X_LD) -g $(BUILD_FOLDER)/examples/example_syscall.o -o $(BUILD_FOLDER)/examples/example_syscall.elf -e loop -T examples/linker_script_$(SMALL_PAGES).ld + debug: DEBUG=1 debug: CFLAGS += $(C_DEBUG_FLAGS) debug: ASM_FLAGS += $(ASM_DEBUG_FLAGS) @@ -61,12 +67,12 @@ debug: $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME) # qemu-system-x86_64 -monitor unix:qemu-monitor-socket,server,nowait -cpu qemu64,+x2apic -cdrom $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME) -serial file:dreamos64.log -m 1G -d int -no-reboot -no-shutdown $(QEMU_SYSTEM) -monitor unix:qemu-monitor-socket,server,nowait -cpu qemu64,+x2apic -cdrom $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME) -serial stdio -m 2G -no-reboot -no-shutdown -$(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME): $(BUILD_FOLDER)/kernel.bin grub.cfg +$(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME): examples $(BUILD_FOLDER)/kernel.bin grub.cfg mkdir -p $(BUILD_FOLDER)/isofiles/boot/grub cp grub.cfg $(BUILD_FOLDER)/isofiles/boot/grub cp $(BUILD_FOLDER)/kernel.bin $(BUILD_FOLDER)/isofiles/boot cp $(BUILD_FOLDER)/kernel.map $(BUILD_FOLDER)/isofiles/boot - cp example_syscall.elf $(BUILD_FOLDER)/isofiles + cp $(BUILD_FOLDER)/examples/example_syscall.elf $(BUILD_FOLDER)/isofiles grub-mkrescue -o $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME) $(BUILD_FOLDER)/isofiles $(BUILD_FOLDER)/%.o: src/%.s diff --git a/examples/example_syscall.s b/examples/example_syscall.s new file mode 100644 index 0000000..84b6ebc --- /dev/null +++ b/examples/example_syscall.s @@ -0,0 +1,7 @@ +extern loop +[bits 64] +loop: + mov rdi, 0x63 + mov rsi, 0x1 + int 0x80 + jmp loop From da09497d197f4ced1816fbc50c7271a8feff1d12 Mon Sep 17 00:00:00 2001 From: Ivan Gualandri Date: Sun, 8 Dec 2024 13:32:59 +0000 Subject: [PATCH 11/15] Various adjustments to load external elf --- Makefile | 5 +++-- docs/kernel/Syscalls.md | 2 +- src/include/kernel/mem/vmm_util.h | 1 + src/kernel/arch/x86_64/mem/vmm_mapping.c | 4 ++-- src/kernel/loaders/elf.c | 2 +- src/kernel/main.c | 5 ++++- src/kernel/mem/vmm_util.c | 4 ++++ src/kernel/scheduling/task.c | 4 ++++ src/kernel/scheduling/thread.c | 3 +-- tests/test_utils.c | 17 ++++++++++++----- 10 files changed, 33 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 1390949..d4b40a4 100644 --- a/Makefile +++ b/Makefile @@ -58,6 +58,7 @@ examples: mkdir -p $(BUILD_FOLDER)/examples ${ASM_COMPILER} -g -felf64 -Fdwarf examples/example_syscall.s -o $(BUILD_FOLDER)/examples/example_syscall.o $(X_LD) -g $(BUILD_FOLDER)/examples/example_syscall.o -o $(BUILD_FOLDER)/examples/example_syscall.elf -e loop -T examples/linker_script_$(SMALL_PAGES).ld + #ld --section-alignment 0x200000 -g $(BUILD_FOLDER)/examples/example_syscall.o -o $(BUILD_FOLDER)/examples/example_syscall.elf -e loop debug: DEBUG=1 debug: CFLAGS += $(C_DEBUG_FLAGS) @@ -67,7 +68,7 @@ debug: $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME) # qemu-system-x86_64 -monitor unix:qemu-monitor-socket,server,nowait -cpu qemu64,+x2apic -cdrom $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME) -serial file:dreamos64.log -m 1G -d int -no-reboot -no-shutdown $(QEMU_SYSTEM) -monitor unix:qemu-monitor-socket,server,nowait -cpu qemu64,+x2apic -cdrom $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME) -serial stdio -m 2G -no-reboot -no-shutdown -$(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME): examples $(BUILD_FOLDER)/kernel.bin grub.cfg +$(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME): $(BUILD_FOLDER)/kernel.bin grub.cfg examples mkdir -p $(BUILD_FOLDER)/isofiles/boot/grub cp grub.cfg $(BUILD_FOLDER)/isofiles/boot/grub cp $(BUILD_FOLDER)/kernel.bin $(BUILD_FOLDER)/isofiles/boot @@ -109,7 +110,7 @@ tests: ${TOOLCHAIN} ${TESTFLAGS} tests/test_kheap.c tests/test_common.c src/kernel/mem/kheap.c src/kernel/mem/bitmap.c src/kernel/mem/pmm.c src/kernel/mem/mmap.c src/kernel/mem/vmm_util.c -o tests/test_kheap.o ${TOOLCHAIN} ${TESTFLAGS} tests/test_vm.c tests/test_common.c src/kernel/arch/x86_64/system/vm.c src/kernel/mem/vmm_util.c -o tests/test_vm.o ${TOOLCHAIN} ${TESTFLAGS} tests/test_vfs.c tests/test_common.c src/fs/vfs.c src/drivers/fs/ustar.c -o tests/test_vfs.o - ${TOOLCHAIN} ${TESTFLAGS} tests/test_utils.c src/kernel/mem/vmm_util.c -o tests/test_utils.o + ${TOOLCHAIN} ${TESTFLAGS} tests/test_utils.c tests/test_common.c src/kernel/mem/vmm_util.c -o tests/test_utils.o ${TOOLCHAIN} ${TESTFLAGS} tests/test_window.c tests/test_common.c src/kernel/graphics/window.c -o tests/test_window.o ./tests/test_mem.o && ./tests/test_kheap.o && ./tests/test_number_conversion.o && ./tests/test_vm.o && ./tests/test_vfs.o && ./tests/test_utils.o && ./tests/test_window.o diff --git a/docs/kernel/Syscalls.md b/docs/kernel/Syscalls.md index 6ccb337..180df38 100644 --- a/docs/kernel/Syscalls.md +++ b/docs/kernel/Syscalls.md @@ -4,7 +4,7 @@ The syscalls are called using the interrupt vector `0x80`. Arguments depend on t # Syscalls List -## 0x01 TEST +## 0x00 TEST The first syscall is reserved for test purpose, and it should be never used. diff --git a/src/include/kernel/mem/vmm_util.h b/src/include/kernel/mem/vmm_util.h index f078768..300258e 100644 --- a/src/include/kernel/mem/vmm_util.h +++ b/src/include/kernel/mem/vmm_util.h @@ -20,6 +20,7 @@ size_t get_number_of_pages_from_size(size_t size); size_t align_value_to_page(size_t value); size_t align_up(size_t value, size_t alignment); +size_t align_down(size_t value, size_t alignment); bool is_address_aligned(size_t value, size_t alignment); size_t vm_parse_flags( size_t flags ); diff --git a/src/kernel/arch/x86_64/mem/vmm_mapping.c b/src/kernel/arch/x86_64/mem/vmm_mapping.c index c8a0bf5..ba231c2 100644 --- a/src/kernel/arch/x86_64/mem/vmm_mapping.c +++ b/src/kernel/arch/x86_64/mem/vmm_mapping.c @@ -24,7 +24,7 @@ void *map_phys_to_virt_addr_hh(void* physical_address, void* address, size_t fla uint8_t user_mode_status = 0; if ( !is_address_higher_half((uint64_t) address) ) { - pretty_log(Verbose, "address is in lower half"); + pretty_logf(Verbose, "address is in lower half: 0x%x", address); flags = flags | VMM_FLAGS_USER_LEVEL; user_mode_status = VMM_FLAGS_USER_LEVEL; } @@ -84,7 +84,7 @@ void *map_phys_to_virt_addr_hh(void* physical_address, void* address, size_t fla } #elif SMALL_PAGES == 0 pd_root[pd_e] = (uint64_t) (physical_address) | HUGEPAGE_BIT | flags | user_mode_status; - pretty_logf(Verbose, " PD Flags: 0x%x entry value pd_root[0x%x]: 0x%x", flags, pd_e, pd_root[pd_e]); + pretty_logf(Verbose, " PD Flags: 0x%x entry value pd_root[0x%x]: 0x%x - address: 0x%x", flags, pd_e, pd_root[pd_e], address); return address; } #endif diff --git a/src/kernel/loaders/elf.c b/src/kernel/loaders/elf.c index ed4a2ad..0b819fe 100644 --- a/src/kernel/loaders/elf.c +++ b/src/kernel/loaders/elf.c @@ -23,7 +23,7 @@ void load_elf(uintptr_t elf_start, uint64_t size) { 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 - 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); + //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); } } } diff --git a/src/kernel/main.c b/src/kernel/main.c index 7d3717b..bb04483 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -266,8 +266,11 @@ void kernel_start(unsigned long addr, unsigned long magic){ char a = 'a'; task_t* idle_task = create_task_from_func("idle", idle, &a, true); idle_thread = idle_task->threads; - //task_t* userspace_task = create_task_from_func("userspace_idle", NULL, &a, false); + #if PAGE_SIZE_IN_BYTES == 0x200000 + task_t* userspace_task = create_task_from_func("userspace_idle", NULL, &a, false); + #else task_t* elf_task = create_task_from_elf("elf_idle", NULL, (Elf64_Ehdr *) (uintptr_t) hhdm_get_variable(elf_module_start_phys)); + #endif //create_thread("ledi", noop2, &c, eldi_task); //create_task("sleeper", noop3, &d); //execute_runtime_tests(); diff --git a/src/kernel/mem/vmm_util.c b/src/kernel/mem/vmm_util.c index 7dde342..a6dba2f 100644 --- a/src/kernel/mem/vmm_util.c +++ b/src/kernel/mem/vmm_util.c @@ -13,6 +13,10 @@ size_t align_up(size_t value, size_t alignment) { return ((value + alignment - 1) / alignment) * alignment; } +size_t align_down(size_t value, size_t alignment) { + return (value / alignment) * alignment; +} + bool is_address_aligned(size_t value, size_t alignment) { if (value % alignment == 0) { return true; diff --git a/src/kernel/scheduling/task.c b/src/kernel/scheduling/task.c index 4f9296c..94c8b83 100644 --- a/src/kernel/scheduling/task.c +++ b/src/kernel/scheduling/task.c @@ -61,6 +61,10 @@ task_t *create_task_from_elf(char *name, void *args, Elf64_Ehdr *elf_header){ uint64_t vaddr_address = align_value_to_page(phdr.p_vaddr); for (int j = 0; j < mem_pages; j++) { pretty_logf(Verbose, "[%d]: Mapping: offset: 0x%x (virtual: 0x%x) in vaddr: 0x%x", j, hhdm_get_phys_address((uintptr_t) offset_address), offset_address, vaddr_address); + if ( !is_address_aligned((size_t) hhdm_get_phys_address(offset_address), PAGE_SIZE_IN_BYTES)) { + pretty_log(Fatal, "Error: module elf phys address is not page aligned"); + } + map_phys_to_virt_addr_hh(hhdm_get_phys_address(offset_address), (void *) vaddr_address, VMM_FLAGS_USER_LEVEL | vmm_hdr_flags | VMM_FLAGS_PRESENT, (uint64_t *) new_task->vmm_data.root_table_hhdm); //I need a mem copy. I need to fopy the content of elf_header + phdr.p_offset into phdr.p_vaddr offset_address += (uint64_t) phdr.p_align; diff --git a/src/kernel/scheduling/thread.c b/src/kernel/scheduling/thread.c index b53d87c..1effa1b 100644 --- a/src/kernel/scheduling/thread.c +++ b/src/kernel/scheduling/thread.c @@ -42,7 +42,7 @@ thread_t* create_thread(char* thread_name, void (*_entry_point)(void *), void* a // This piece of code is temporary, just to test a userspace task, it run just an infinite loop. pretty_logf(Verbose, "vmm_data address: 0x%x", &(parent_task->vmm_data)); if (is_elf ) { - pretty_logf(Verbose, "Preparing to launch an ELF. entry_pint = 0x%x", (uint64_t) _entry_point); + pretty_logf(Verbose, "Preparing to launch an ELF. entry_point = 0x%x", (uint64_t) _entry_point); new_thread->execution_frame->rip = (uint64_t)_entry_point; } else { new_thread->execution_frame->rip = prepare_userspace_function(&(parent_task->vmm_data)); @@ -75,7 +75,6 @@ thread_t* create_thread(char* thread_name, void (*_entry_point)(void *), void* a while(1); } // We need to allocate a new stack for each thread - //void* stack_pointer = kmalloc(THREAD_DEFAULT_STACK_SIZE); void* stack_pointer = vmm_alloc(THREAD_DEFAULT_STACK_SIZE, VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE | VMM_FLAGS_STACK, &(parent_task->vmm_data)); if (stack_pointer == NULL) { pretty_log(Fatal, "rsp is null - PANIC!"); diff --git a/tests/test_utils.c b/tests/test_utils.c index 845a988..3b428d6 100644 --- a/tests/test_utils.c +++ b/tests/test_utils.c @@ -1,17 +1,24 @@ +#include #include #include #include +void test_utils(); + int main() { printf("Testing VMM Utility function -\n"); + test_utils(); +} + +void test_utils() { size_t number_of_pages = get_number_of_pages_from_size(0x900); - printf("\t [test_utils] (get_number_of_pages_from_size): Testing number of pages for 0x900, should be 1: %ld\n", number_of_pages); + printf("\t[test_utils] (get_number_of_pages_from_size): Testing number of pages for 0x900, should be 1: %ld\n", number_of_pages); assert(number_of_pages == 1); number_of_pages = get_number_of_pages_from_size(0x0); - printf("\t [test_utils] (get_number_of_pages_from_size): Testing number of pages for 0x0, should be 0: %ld\n", number_of_pages); + printf("\t[test_utils] (get_number_of_pages_from_size): Testing number of pages for 0x0, should be 0: %ld\n", number_of_pages); assert(align_value_to_page(0x100) == 0x200000); - printf("\t [test_utils] (align_value_to_page): Testing alignment for 0x100, should be 0x200000: %lx\n", align_value_to_page(0x100)); + printf("\t[test_utils] (align_value_to_page): Testing alignment for 0x100, should be 0x200000: %lx\n", align_value_to_page(0x100)); assert(align_value_to_page(0x200015) == 0x400000); - printf("\t [test_utils] (align_value_to_page): Testing alignment for 0x100, should be 0x200015: %lx\n", align_value_to_page(0x200015)); - + pretty_assert(0x200000, align_down(0x3c7000, 0x200000), ==, "Testing align_down"); + pretty_assert(0x600000, align_down(0x6c7000, 0x200000), ==, "Testing align_down"); } From f3f3a66a0194c253f5149047a60e9afa87acc3f0 Mon Sep 17 00:00:00 2001 From: Ivan Gualandri Date: Sun, 8 Dec 2024 19:29:15 +0000 Subject: [PATCH 12/15] Add linker scripts for the example --- examples/linker_script_0.ld | 31 +++++++++++++++++++++++++++++++ examples/linker_script_1.ld | 31 +++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 examples/linker_script_0.ld create mode 100644 examples/linker_script_1.ld diff --git a/examples/linker_script_0.ld b/examples/linker_script_0.ld new file mode 100644 index 0000000..34cd489 --- /dev/null +++ b/examples/linker_script_0.ld @@ -0,0 +1,31 @@ +ENTRY(loop) + +SECTIONS { + + . = 8M; + + .text : ALIGN (2M) + { + *(.text) + *(.text.*) + } + + .rodata : ALIGN (2M) + { + *(.rodata) + *(.rodata.*) + } + + .data : ALIGN (2M) + { + *(.data) + *(.data.*) + } + + .bss : ALIGN (2M) + { + *(.bss) + } + +} + diff --git a/examples/linker_script_1.ld b/examples/linker_script_1.ld new file mode 100644 index 0000000..bea1f48 --- /dev/null +++ b/examples/linker_script_1.ld @@ -0,0 +1,31 @@ +ENTRY(loop) + +SECTIONS { + + . = 4M; + + .text : ALIGN (4K) + { + *(.text) + *(.text.*) + } + + .rodata : ALIGN (4K) + { + *(.rodata) + *(.rodata.*) + } + + .data : ALIGN (4K) + { + *(.data) + *(.data.*) + } + + .bss : ALIGN (4K) + { + *(.bss) + } + +} + From 0f7249e6dd20efdd57b0babe0d2d399b6d9c1684 Mon Sep 17 00:00:00 2001 From: Ivan Gualandri Date: Tue, 17 Dec 2024 13:48:52 +0000 Subject: [PATCH 13/15] fix clang issue --- Makefile | 3 ++- build/Common.mk | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d4b40a4..9342c24 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,7 @@ ifeq ($(TOOLCHAIN), gcc) else ifeq ($(TOOLCHAIN), clang) X_CC = clang X_LD = ld.lld + LD_FLAGS += -z lrodata-after-bss else $(error "Unknown compiler toolchain") endif @@ -95,7 +96,7 @@ $(BUILD_FOLDER)/kernel.bin: $(OBJ_ASM_FILE) $(OBJ_C_FILE) $(OBJ_FONT_FILE) src/l echo $(OBJ_ASM_FILE) echo $(OBJ_FONT_FILE) echo $(IS_WORKFLOW) - $(X_LD) -n -o $(BUILD_FOLDER)/kernel.bin -T src/linker.ld $(OBJ_ASM_FILE) $(OBJ_C_FILE) $(OBJ_FONT_FILE) -Map $(BUILD_FOLDER)/kernel.map + $(X_LD) $(LD_FLAGS) -n -o $(BUILD_FOLDER)/kernel.bin -T src/linker.ld $(OBJ_ASM_FILE) $(OBJ_C_FILE) $(OBJ_FONT_FILE) -Map $(BUILD_FOLDER)/kernel.map gdb: DEBUG=1 gdb: CFLAGS += $(C_DEBUG_FLAGS) diff --git a/build/Common.mk b/build/Common.mk index ab99e86..6f1f28e 100644 --- a/build/Common.mk +++ b/build/Common.mk @@ -26,6 +26,8 @@ CFLAGS := -std=gnu99 \ -mno-red-zone \ -mno-sse \ -mcmodel=large \ + -fno-pie \ + -fno-pic \ -fno-stack-protector CFLAGS += $(DEF_FLAGS) @@ -46,5 +48,7 @@ TESTFLAGS := -std=gnu99 \ -DSMALL_PAGES=0 \ -D_TEST_=1 +LD_FLAGS := + PRJ_FOLDERS := src TEST_FOLDER := tests From d308ec64cf84bffbc217c83874444a50ea10a4de Mon Sep 17 00:00:00 2001 From: Ivan Gualandri Date: Tue, 17 Dec 2024 23:06:30 +0000 Subject: [PATCH 14/15] Remove unnecesary binary file --- example_syscall.elf | Bin 5200 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 example_syscall.elf diff --git a/example_syscall.elf b/example_syscall.elf deleted file mode 100755 index 0f54d8635dd705029409a078bf13629e0ae1e6c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5200 zcmeHL%Ss$U6us4Bvco6wD$Jx{ZPe2AwRDMMy$G2)Jshor+GF>6Y$NbQM3r zfA9y~x=Hc_`I4-XZ5GMB^=Lbl5yf@YFm-O7drm*jOfR}VzkKs5U<~XCU<=eL>M2Uk z0MU$90Q6u30-W0rD(%E|3oGl;cxieTA<_h$;{las4d#3nJ6Z-7Yn|ae_yl|cJ^`PA zPrxVO6YvT61bhNM0iS?Rz$b9`1itQ}_6xm@e?R;2>nUQO%%Pgyw{cBg&m7B^T86CF z+BbRR#R(rB4#iqrL2^)xL~<S(YnSh^v+}=YZBHHz6+$CwcmS61AvL27HQhJA9zJYIE^sp!nAx*QYN-N1r390CF z$r18CKwO=UB+n3Ksqw&8Qk+PL`yxBqPkG7neNoxvApcm{nrB%lj_qnV$VGkG_bwLD zN!ihFqlV4N?DN$7Iks)k!V(tbcSpzgSDc2crM}CNWy|>8TXeP0Z}49jKmDG~;rd@= z)8$D2&G@&Q<}q6G>L<_<(jN@Rxdxa*B%OIqVczg!oa!lKlzvb?^;PV&VOb6 IA8zsg1>QGY5dZ)H From 2b97a353ac52bef9e7f6da05ed3e245c49aa6eca Mon Sep 17 00:00:00 2001 From: Ivan Gualandri Date: Wed, 18 Dec 2024 22:51:11 +0000 Subject: [PATCH 15/15] Update Readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 35fb5e0..2cf9e93 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ But at kernel level several things have been implemented: * Basic Virtual Memory implementation * Initial Userspace support (so far can run only an idle userspace thread) * Basic syscall mechanism (altough no real syscalls are implemented, just one that prints the string "example") +* Initial basic ELF support (from kernel module) ## Prerequisites: