#include "../include/task.h" #include "../include/stdio.h" #include "../include/paging.h" #include "../include/string.h" #include Process* current = 0; Process* queue = 0; uint32_t irq_disable_counter = 0; uint32_t pid_counter; uint32_t task_count; #define KSTACKSIZE 4096 #define USTACKSIZE 4096 extern void trapret(void); extern void switchProcess(Process* next); extern Process* queue; extern Process* current; extern uint32_t pid_counter; extern uint32_t task_count; 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); map_page(p_physical, (void*)p, PAGE_PRESENT | PAGE_RW); memset(p, 0, sizeof(Process)); p->pid = ++pid_counter; p->state = Ready; p->ring = ring; // Выделяем стек ядра void *kstack_physical = alloc_page(); p->kstack = (char*)((uint32_t)kstack_physical+0xC0000000); map_page(kstack_physical, p->kstack, PAGE_PRESENT | PAGE_RW); debug_log("kstack: %X!!!!!!!!!!!!\n", 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->es = p->tf->ds; p->tf->fs = p->tf->ds; p->tf->gs = 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->pagedir = pagedir;//(uint32_t*)create_page_dir(); 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_in_directory(p->pagedir, user_stack_physical, (void*)user_stack_virtual_base, PAGE_PRESENT | PAGE_RW | PAGE_USER); // Флаги 0x7 */ p->tf->usermode_esp = user_esp;//user_stack_virtual_top; } sp -= sizeof(Context); p->context = (Context*)sp; memset(p->context, 0, sizeof(Context)); p->context->eip = (uint32_t)trapret; p->kesp = (uint32_t)sp; p->next = 0; if (!queue) { queue = p; current = queue; } else { Process* curr = queue; while (curr->next) curr = curr->next; curr->next = p; } task_count++; return p; } // Остальные функции остаются без изменений void scheduler_lock() { asm volatile("cli"); irq_disable_counter++; } void scheduler_unlock() { irq_disable_counter--; if (irq_disable_counter == 0) asm volatile("sti"); } void schedule() { if (!current) return; Process* next = current->next; if (!next) next = queue; if (next != current) { switchProcess(next); } } void idle() { while (1) {} } void task1() { while (1) { printf("task1\n"); } } void task2() { int a = 0; while (1) { a++; printf("task2 %X\n", a); } } void jump_usermode2(void) ; void scheduler_init() { uint32_t* kernel_tasks_pagedir = (uint32_t*)create_page_dir(); task_create((uint32_t)idle, 0, 0, kernel_tasks_pagedir); } void handle_syscall(TrapFrame *tf) { debug_log("EAX: %X ", tf->eax); debug_log("EBX: %X ", tf->ebx); debug_log("ECX: %s ", tf->ecx); debug_log("EDX: %X\n", tf->edx); }