From c808a5d2958279af1d2a2d6f666bd3f1e38c01c5 Mon Sep 17 00:00:00 2001 From: Ruslan Isaev Date: Thu, 29 May 2025 21:18:09 +0300 Subject: [PATCH] fix creating ring 3 tasks finally --- src/tasking/switch.asm | 19 ++++++++------- src/tasking/task.c | 52 +++++++++++++++++++++++++----------------- 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/src/tasking/switch.asm b/src/tasking/switch.asm index acdfa9c..12e79ca 100644 --- a/src/tasking/switch.asm +++ b/src/tasking/switch.asm @@ -15,29 +15,28 @@ global switchProcess extern current extern trapret +; void switchProcess(Process* next_process_ptr) switchProcess: - mov eax, [esp + 4] ; eax = old - mov edx, [esp + 8] ; edx = new + mov edx, [esp + 4] ; edx = next_process_ptr (получаем аргумент СРАЗУ) + cli ; Запретить прерывания push ebp push ebx push esi push edi - mov [eax+4], esp - mov esp, [edx+4] + mov eax, [current] + mov [eax + 4], esp ; current->kesp = esp - ;mov eax, [edx+12] - ;sub eax, 0xC0000000 - ;mov cr3, eax + ; edx уже содержит next_process_ptr + mov esp, [edx + 4] ; esp = next_process_ptr->kesp + mov [current], edx ; current = next_process_ptr pop edi pop esi pop ebx pop ebp - - - ret ; Для ring 0 просто возвращаемся + ret trapret: diff --git a/src/tasking/task.c b/src/tasking/task.c index a109b90..58846b3 100644 --- a/src/tasking/task.c +++ b/src/tasking/task.c @@ -32,44 +32,54 @@ static void processStartup() Process* task_create(uint32_t func, void** args, uint32_t arg_count, uint32_t ring) { - Process* p = alloc_page();//heap_alloc(sizeof(Process)); + Process* p = (Process*)alloc_page();//heap_alloc(sizeof(Process)); + memset(p, 0, sizeof(Process)); p->pid = ++pid_counter; p->state = Ready; p->ring = ring; // Выделяем стек ядра - p->kstack = alloc_page();//heap_alloc(KSTACKSIZE); - map_page(p->kstack, p->kstack, 0x7); + p->kstack = (char*)alloc_page();//heap_alloc(KSTACKSIZE); + map_page(p->kstack, p->kstack, 0x3); printf("kstack: %X!!!!!!!!!!!!\n", p->kstack); - uint8_t* sp = (uint8_t*)(p->kstack); + uint8_t* sp = (uint8_t*)(p->kstack + KSTACKSIZE); sp -= sizeof(TrapFrame); p->tf = (TrapFrame*)sp; memset(p->tf, 0, sizeof(TrapFrame)); - p->tf->cs = ring == 3 ? (SEG_UCODE) | DPL_USER : (SEG_KCODE); - p->tf->ds = ring == 3 ? (SEG_UDATA) | DPL_USER : (SEG_KDATA); + + p->tf->cs = ring == 3 ? (SEG_UCODE | DPL_USER) : (SEG_KCODE); + p->tf->ds = ring == 3 ? (SEG_UDATA | DPL_USER) : (SEG_KDATA); p->tf->es = p->tf->ds; p->tf->fs = p->tf->ds; p->tf->gs = p->tf->ds; - p->tf->usermode_ss = p->tf->ds; + + p->tf->usermode_ss = ring == 3 ? (SEG_UDATA | DPL_USER) : (SEG_KDATA); + p->tf->eflags = FL_IF; p->tf->eip = (uint32_t)func; - p->tf->usermode_esp = 0x800000; // Предполагаем, что пользовательский стек настроен + + if(ring == 3) + { + 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(user_stack_physical, (void*)user_stack_virtual_base, 0x7/*PTE_PRESENT | PTE_READ_WRITE | PTE_USER*/); // Флаги 0x7 + + } sp -= sizeof(Context); p->context = (Context*)sp; - p->context->eip = (uint32_t)trapret; - // Настраиваем начальный контекст - //sp -= 5; // Место для edi, esi, ebx, ebp, eip - //sp -= sizeof(Context); - p->context->edi = 0; - p->context->esi = 0; - p->context->ebx = 0; - p->context->ebp = 0; + memset(p->context, 0, sizeof(Context)); - p->page_directory = kernel_page_directory; + p->context->eip = (uint32_t)trapret; + p->kesp = (uint32_t)sp; + + p->page_directory = kpage_dir; p->next = 0; @@ -111,7 +121,7 @@ void schedule() if (next != current) { //loadPageDirectory(next->page_directory); - printf("switching to %X\n", next->pid); + //printf("switching to %X\n", next->pid); switchProcess(next); } } @@ -142,10 +152,10 @@ void scheduler_init() task_create((uint32_t)idle, NULL, 0, 0); void* args1[] = {(void*)42, (void*)"ebalo"}; - //task_create((EntryPoint)task1, args1, 2, 0); + task_create((uint32_t)task1, args1, 2, 0); void* args2[] = {(void*)69, (void*)420}; //task_create((EntryPoint)&task2, args2, 2, 0); - //jump_usermode2(); + jump_usermode2(); } #include "../include/string.h" @@ -211,7 +221,7 @@ void jump_usermode2(void) { (code_pte & 0x4) ? "user" : "supervisor"); task_create((uint32_t)user_code_virt, NULL, 0, 3); - //task_create(second_user_code_virt, NULL, 0, 3); + task_create((uint32_t)second_user_code_virt, NULL, 0, 3); return; // Switch to user mode with interrupts enabled