diff --git a/grubshit/aaa b/grubshit/aaa new file mode 100755 index 0000000..ab2434a Binary files /dev/null and b/grubshit/aaa differ diff --git a/grubshit/aaa.asm b/grubshit/aaa.asm new file mode 100644 index 0000000..4a0fd19 --- /dev/null +++ b/grubshit/aaa.asm @@ -0,0 +1,15 @@ +section .text + global _start ;must be declared for using gcc +_start: ;tell linker entry point + mov edx, len ;message length + mov ecx, msg ;message to write + mov ebx, 1 ;file descriptor (stdout) + mov eax, 4 ;system call number (sys_write) + int 0x80 ;call kernel + mov eax, 1 ;system call number (sys_exit) + int 0x80 ;call kernel + +section .data + +msg db 'Hello, world!',0xa ;our dear string +len equ $ - msg ;length of our dear string diff --git a/grubshit/aaa.o b/grubshit/aaa.o new file mode 100644 index 0000000..ca2e1f3 Binary files /dev/null and b/grubshit/aaa.o differ diff --git a/include/task.h b/include/task.h index 6d0f9d3..7f1cae5 100644 --- a/include/task.h +++ b/include/task.h @@ -60,7 +60,7 @@ typedef struct Process struct Process* next; // Следующий процесс } Process; -Process* task_create(uint32_t func, void** args, uint32_t arg_count, uint32_t ring, uint32_t* pagedir); +Process* task_create(uint32_t func, uint32_t user_esp, uint32_t ring, uint32_t* pagedir); void scheduler_init(); void schedule(); void scheduler_lock(); diff --git a/src/tasking/exec_from_file.c b/src/tasking/exec_from_file.c index ac0dbd9..ba74826 100644 --- a/src/tasking/exec_from_file.c +++ b/src/tasking/exec_from_file.c @@ -8,6 +8,10 @@ #define DivRoundUp(number, divisor) ((number + divisor - 1) / divisor) +#define USER_STACK_TOP 0xBFFFFFF0//0xC0000000 // Top of user space memory +#define USER_STACK_SIZE 0x4000 // 16KB stack (4 pages) +#define USER_STACK_BOTTOM (USER_STACK_TOP - USER_STACK_SIZE) + disk_ops_t ops1 = { .read = ata_read, @@ -19,16 +23,16 @@ static fat_t g_fat; int read_file(const char* path, uint8_t** buffer) { file_t file; - int err = fat_fopen(&file, path, "r"); - if (err) - return err; + int err = fat_fopen(&file, path, "r"); + if (err) + return err; uint32_t file_size = fat_fsize(&file); printf("file_size: %X\n", file_size); - uint8_t buf[512]; - //memset(buf, 0, 512); - printf("heh\n"); + uint8_t buf[512]; + //memset(buf, 0, 512); + printf("heh\n"); *buffer = (uint8_t*)malloc(file_size); //memset(*buffer, 0, file_size); @@ -36,35 +40,35 @@ int read_file(const char* path, uint8_t** buffer) printf("eeee\n"); - int cnt = fat_fread(&file, *buffer, file_size); + int cnt = fat_fread(&file, *buffer, file_size); - /*for (;;) - { - int cnt = fat_fread(&file, buf, 512); - if (cnt < 0) - return cnt; + /*for (;;) + { + int cnt = fat_fread(&file, buf, 512); + if (cnt < 0) + return cnt; + + //printf("%s\n", buf); + memcpy(current, buf, 512); + current += 512; + + if (cnt < 512) + break; + }*/ - //printf("%s\n", buf); - memcpy(current, buf, 512); - current += 512; - - if (cnt < 512) - break; - }*/ - - return fat_fclose(&file); + return fat_fclose(&file); } void exec_from_file(const char* filename) { - asm volatile("cli"); + asm volatile("cli"); int err, cnt; err = fat_mount(&ops1, 0, &g_fat, "ebalo"); uint8_t* file; - int result = read_file("/ebalo/testfile", &file); + int result = read_file("/ebalo/aaa", &file); printf("result: %X\n", result); printf("buffer: %s\n", file); @@ -86,47 +90,74 @@ void exec_from_file(const char* filename) for(int i = 0; i < program_header_table_entry_count; i++) { - Elf32_Phdr *elf_phdr = (Elf32_Phdr *)((uint32_t)file + elf_ehdr->e_phoff + - i * elf_ehdr->e_phentsize); + Elf32_Phdr *elf_phdr = (Elf32_Phdr *)((uint32_t)file + elf_ehdr->e_phoff + + i * elf_ehdr->e_phentsize); - printf("HEADER %X, type: 0x%X, vaddr: 0x%X, paddr: 0x%X, memsz: 0x%X\n", i, elf_phdr->p_type, elf_phdr->p_vaddr, elf_phdr->p_paddr, elf_phdr->p_memsz); - if(elf_phdr->p_type != PT_LOAD) - { - printf("not PT_LOAD, skipping...\n"); - continue; - } - int pages_needed = (elf_phdr->p_memsz / 0x1000) + 1; - printf("pages needed: %X\n", pages_needed); + printf("HEADER %X, type: 0x%X, vaddr: 0x%X, paddr: 0x%X, memsz: 0x%X\n", i, elf_phdr->p_type, elf_phdr->p_vaddr, elf_phdr->p_paddr, elf_phdr->p_memsz); + if(elf_phdr->p_type != PT_LOAD) + { + printf("not PT_LOAD, skipping...\n"); + continue; + } - for(int j = 0; j < pages_needed; j++) - { - uint32_t vaddr = (elf_phdr->p_vaddr & ~0xFFF) + j * 0x1000; - void* phys_addr = alloc_page(); + int pages_needed = DivRoundUp(elf_phdr->p_memsz, 0x1000);//(elf_phdr->p_memsz / 0x1000) + 1; + printf("pages needed: %X\n", pages_needed); - printf("mapping 0x%X -> 0x%X\n", phys_addr, vaddr); - //map_page_in_directory(proc_pd, phys_addr, (void*)vaddr, PAGE_PRESENT | PAGE_RW | PAGE_USER); - map_page(phys_addr, (void*)vaddr, PAGE_PRESENT | PAGE_RW | PAGE_USER); - } + for(int j = 0; j < pages_needed; j++) + { + uint32_t vaddr = (elf_phdr->p_vaddr & ~0xFFF) + j * 0x1000; + void* phys_addr = alloc_page(); - + printf("mapping 0x%X -> 0x%X\n", phys_addr, vaddr); + map_page(phys_addr, (void*)vaddr, PAGE_PRESENT | PAGE_RW | PAGE_USER); + } - memcpy((void*)elf_phdr->p_vaddr, file+elf_phdr->p_offset, elf_phdr->p_filesz); + memcpy((void*)elf_phdr->p_vaddr, file+elf_phdr->p_offset, elf_phdr->p_filesz); + + if (elf_phdr->p_memsz > elf_phdr->p_filesz) { + uint32_t bss_start = elf_phdr->p_vaddr + elf_phdr->p_filesz; + uint32_t bss_end = elf_phdr->p_vaddr + elf_phdr->p_memsz; + memset((void*)bss_start, 0, bss_end - bss_start); + } - - - uint32_t file_start = (elf_phdr->p_vaddr & ~0xFFF) + elf_phdr->p_filesz; - uint32_t file_end = (elf_phdr->p_vaddr & ~0xFFF) + pages_needed * 0x1000; - memset((void*)file_start, 0, file_end - file_start); - - printf("p_filesz: 0x%X (%X)\n", elf_phdr->p_filesz, elf_phdr->p_filesz); - - - - printf("================================\n\n\n\n"); + printf("p_filesz: 0x%X (%X)\n", elf_phdr->p_filesz, elf_phdr->p_filesz); + printf("================================\n\n\n\n"); } - - set_page_dir(curr_pd_phys); - Process* p_task1 = task_create(elf_ehdr->e_entry, NULL, 0, 3, proc_pd); - - asm volatile("sti"); + + printf("setting up the user stack...\n"); + + //TODO: i think this thing allocates more pages than needed + for (uint32_t vaddr = USER_STACK_BOTTOM; vaddr <= USER_STACK_TOP; vaddr += PAGE_SIZE) { + void* phys_addr = alloc_page(); + if(!phys_addr) + { + printf("error allocating user stack page, aborting...\n"); + set_page_dir(curr_pd_phys); + //TODO: free previously allocated pages + return; + } + map_page(phys_addr, (void*)(vaddr & ~0xFFF), PAGE_PRESENT | PAGE_RW | PAGE_USER); + printf("mapping stack 0x%X -> 0x%X (0x%X)\n", (uint32_t)phys_addr, vaddr, (vaddr & ~0xFFF)); + memset((void*)(vaddr & ~0xFFF), 0, PAGE_SIZE); // Add this + } + /* + uint32_t user_esp = USER_STACK_TOP; + + // envp (environment pointer array) = NULL terminator + user_esp -= 4; + *(uint32_t*)user_esp = 0; + + // argv (argument pointer array) = NULL terminator + user_esp -= 4; + *(uint32_t*)user_esp = 0; + + // argc (argument count) = 0 + user_esp -= 4; + *(uint32_t*)user_esp = 0; + */ + + set_page_dir(curr_pd_phys); + Process* p_task1 = task_create(elf_ehdr->e_entry, USER_STACK_TOP, 3, proc_pd); + + asm volatile("sti"); } \ No newline at end of file diff --git a/src/tasking/sys_exit.asm b/src/tasking/sys_exit.asm index 3234153..896ff49 100644 --- a/src/tasking/sys_exit.asm +++ b/src/tasking/sys_exit.asm @@ -16,10 +16,27 @@ sys_exit_handler: mov fs, ax mov gs, ax + mov eax, [esp+44] ; System call number + mov ebx, [esp+32] ; Arg1 + mov ecx, [esp+40] ; Arg2 + mov edx, [esp+36] ; Arg3 + mov esi, [esp+28] ; Arg4 + mov edi, [esp+24] ; Arg5 + + ; Print debug information + push edi ; arg5 + push esi ; arg4 + push edx ; arg3 + push ecx ; arg2 + push ebx ; arg1 + push eax ; syscall number + push syscall_debug_fmt + ; Выполняем действие - push sys_exit_msg + ;push sys_exit_msg call printf - add esp, 4 + ;add esp, 4 + add esp, 28 ; Восстанавливаем сегменты Ring 3 pop gs @@ -47,3 +64,4 @@ heh: section .data sys_exit_msg: db "Returned from Ring 3", 0 +syscall_debug_fmt: db "Syscall #%x, args: 0x%x 0x%x 0x%x 0x%x 0x%x", 10, 0 \ No newline at end of file diff --git a/src/tasking/task.c b/src/tasking/task.c index f8bab8b..067e3cb 100644 --- a/src/tasking/task.c +++ b/src/tasking/task.c @@ -22,7 +22,7 @@ extern Process* current; extern uint32_t pid_counter; extern uint32_t task_count; -Process* task_create(uint32_t func, void** args, uint32_t arg_count, uint32_t ring, uint32_t* pagedir) +Process* task_create(uint32_t func, uint32_t user_esp, uint32_t ring, uint32_t* pagedir) { void *p_physical = alloc_page(); Process* p = (Process*)((uint32_t)p_physical+0xC0000000); @@ -60,14 +60,15 @@ Process* task_create(uint32_t func, void** args, uint32_t arg_count, uint32_t ri if(ring == 3) { - void* user_stack_physical = alloc_page(); + /*void* user_stack_physical = alloc_page(); uint32_t user_stack_virtual_top = 0xBFFFF000 - ((p->pid -1) * (USTACKSIZE + 4096)); // Уникальный верх стека для каждого процесса uint32_t user_stack_virtual_base = user_stack_virtual_top - USTACKSIZE; map_page_in_directory(p->pagedir, user_stack_physical, (void*)user_stack_virtual_base, PAGE_PRESENT | PAGE_RW | PAGE_USER); // Флаги 0x7 + */ - p->tf->usermode_esp = user_stack_virtual_top; + p->tf->usermode_esp = user_esp;//user_stack_virtual_top; } @@ -145,7 +146,7 @@ void scheduler_init() { uint32_t* kernel_tasks_pagedir = (uint32_t*)create_page_dir(); - task_create((uint32_t)idle, NULL, 0, 0, kernel_tasks_pagedir); + task_create((uint32_t)idle, 0, 0, kernel_tasks_pagedir); /*void* args1[] = {(void*)42, (void*)"ebalo"}; task_create((uint32_t)task1, args1, 2, 0, kernel_tasks_pagedir); @@ -195,7 +196,7 @@ void jump_usermode2(void) { uint32_t* proc_pd = create_page_dir(); uint32_t* proc2_pd = create_page_dir(); - Process* p_task1 = task_create(0x400000, NULL, 0, 3, proc_pd); + /*Process* p_task1 = task_create(0x400000, NULL, 3, proc_pd); Process* p_task2 = task_create(0x400000, NULL, 0, 3, proc2_pd); if (map_page_in_directory(p_task1->pagedir, @@ -216,6 +217,6 @@ void jump_usermode2(void) { printf("jump_usermode2: Failed to map user code into task's PD for PID %d\n", p_task2->pid); // TODO: Terminate/cleanup p_task1, free code_phys_task1 return; - } + }*/ scheduler_unlock(); }