tasking: fix ELF file execution

This commit is contained in:
2025-06-07 18:18:05 +03:00
parent 9f721a72b7
commit 5fa2393fd6
7 changed files with 133 additions and 68 deletions
Executable
BIN
View File
Binary file not shown.
+15
View File
@@ -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
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -60,7 +60,7 @@ typedef struct Process
struct Process* next; // Следующий процесс struct Process* next; // Следующий процесс
} Process; } 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 scheduler_init();
void schedule(); void schedule();
void scheduler_lock(); void scheduler_lock();
+45 -14
View File
@@ -8,6 +8,10 @@
#define DivRoundUp(number, divisor) ((number + divisor - 1) / divisor) #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 = disk_ops_t ops1 =
{ {
.read = ata_read, .read = ata_read,
@@ -64,7 +68,7 @@ void exec_from_file(const char* filename)
uint8_t* file; uint8_t* file;
int result = read_file("/ebalo/testfile", &file); int result = read_file("/ebalo/aaa", &file);
printf("result: %X\n", result); printf("result: %X\n", result);
printf("buffer: %s\n", file); printf("buffer: %s\n", file);
@@ -95,7 +99,8 @@ void exec_from_file(const char* filename)
printf("not PT_LOAD, skipping...\n"); printf("not PT_LOAD, skipping...\n");
continue; continue;
} }
int pages_needed = (elf_phdr->p_memsz / 0x1000) + 1;
int pages_needed = DivRoundUp(elf_phdr->p_memsz, 0x1000);//(elf_phdr->p_memsz / 0x1000) + 1;
printf("pages needed: %X\n", pages_needed); printf("pages needed: %X\n", pages_needed);
for(int j = 0; j < pages_needed; j++) for(int j = 0; j < pages_needed; j++)
@@ -104,29 +109,55 @@ void exec_from_file(const char* filename)
void* phys_addr = alloc_page(); void* phys_addr = alloc_page();
printf("mapping 0x%X -> 0x%X\n", phys_addr, vaddr); 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); 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 file_start = (elf_phdr->p_vaddr & ~0xFFF) + elf_phdr->p_filesz; uint32_t bss_end = elf_phdr->p_vaddr + elf_phdr->p_memsz;
uint32_t file_end = (elf_phdr->p_vaddr & ~0xFFF) + pages_needed * 0x1000; memset((void*)bss_start, 0, bss_end - bss_start);
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("p_filesz: 0x%X (%X)\n", elf_phdr->p_filesz, elf_phdr->p_filesz);
printf("================================\n\n\n\n"); printf("================================\n\n\n\n");
} }
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); set_page_dir(curr_pd_phys);
Process* p_task1 = task_create(elf_ehdr->e_entry, NULL, 0, 3, proc_pd); //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"); asm volatile("sti");
} }
+20 -2
View File
@@ -16,10 +16,27 @@ sys_exit_handler:
mov fs, ax mov fs, ax
mov gs, 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 call printf
add esp, 4 ;add esp, 4
add esp, 28
; Восстанавливаем сегменты Ring 3 ; Восстанавливаем сегменты Ring 3
pop gs pop gs
@@ -47,3 +64,4 @@ heh:
section .data section .data
sys_exit_msg: db "Returned from Ring 3", 0 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
+7 -6
View File
@@ -22,7 +22,7 @@ extern Process* current;
extern uint32_t pid_counter; extern uint32_t pid_counter;
extern uint32_t task_count; 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(); void *p_physical = alloc_page();
Process* p = (Process*)((uint32_t)p_physical+0xC0000000); 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) 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_top = 0xBFFFF000 - ((p->pid -1) * (USTACKSIZE + 4096)); // Уникальный верх стека для каждого процесса
uint32_t user_stack_virtual_base = user_stack_virtual_top - USTACKSIZE; 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 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(); 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"}; /*void* args1[] = {(void*)42, (void*)"ebalo"};
task_create((uint32_t)task1, args1, 2, 0, kernel_tasks_pagedir); 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* proc_pd = create_page_dir();
uint32_t* proc2_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); Process* p_task2 = task_create(0x400000, NULL, 0, 3, proc2_pd);
if (map_page_in_directory(p_task1->pagedir, 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); 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 // TODO: Terminate/cleanup p_task1, free code_phys_task1
return; return;
} }*/
scheduler_unlock(); scheduler_unlock();
} }