diff --git a/include/arch.h b/include/arch.h index fbd32ce..c08d6b3 100644 --- a/include/arch.h +++ b/include/arch.h @@ -14,10 +14,16 @@ #define STACK_SIZE 8192 // 1MB -typedef struct task { - uint64_t id; - struct frame *state; - struct task *next; +typedef struct thread { + uint64_t id; // Идентификатор задачи + uint64_t priority; // Приоритет задачи + void *entry_point; // Точка входа в задачу + uint64_t status; // Состояние задачи + void *stack; // Указатель на стек + void *rsp; // Указатель на RSP + uint64_t stack_size; // Размер стека задачи + struct task *next; // Следующий поток + struct task *last; // Предыдущий поток } __attribute__((packed)) task_t; struct frame { diff --git a/include/version.h b/include/version.h index 3cc938a..4fc9641 100644 --- a/include/version.h +++ b/include/version.h @@ -1,3 +1,3 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 1 -#define VERSION_BUILD 905 +#define VERSION_BUILD 915 diff --git a/kernel/mod.c b/kernel/mod.c index d6db0e8..d331830 100644 --- a/kernel/mod.c +++ b/kernel/mod.c @@ -101,7 +101,7 @@ void mod_init( ) { continue; } - module_info_t (*module_init)(env_t * env) = + module_info_t (*module_init)(env_t *env) = (module_info_t(*)(env_t * env)) elf_entry((elf64_header_t *)module_ptr->address); // LOG("\t->Точка входа: 0x%x\n", module_init); diff --git a/kernel/task.c b/kernel/task.c index 4f7431e..92ffa5d 100644 --- a/kernel/task.c +++ b/kernel/task.c @@ -10,18 +10,24 @@ #include #include -static volatile uint64_t pid = 0; +static volatile uint64_t next_thread_id = 0; +static task_t *last_task = NULL; static task_t *kernel_task = NULL; task_t *current_task = NULL; void task_switch(struct frame *state) { // Смена потоков + asm volatile("cli"); + asm volatile("pushf"); task_t *prev_task = current_task; - if (current_task == NULL) { return; } + if (current_task->next == NULL) { current_task = kernel_task; } LOG("Смена потоков %u -> ", current_task->id); + + asm volatile("mov %%rsp, %0" : "=a"(current_task->rsp)); + current_task = current_task->next; if (current_task == NULL) { @@ -33,61 +39,45 @@ void task_switch(struct frame *state) { fb_printf("%u\n", current_task->id); - // Сохранение предыдущего состояния - prev_task->state->rip = state->rip; - prev_task->state->rsp = state->rsp; - prev_task->state->rbp = state->rbp; - - // Восстановление следующего состояния - // LOG("Смена rsp\n"); - state->rsp = current_task->state->rsp; - // LOG("Смена rbp\n"); - state->rbp = current_task->state->rbp; - // LOG("Смена rip\n"); - state->rip = current_task->state->rip; - // LOG("Конец!\n"); + asm volatile("mov %0, %%rsp" ::"a"(current_task->rsp)); + asm volatile("popf"); } task_t *task_new_thread(void (*func)(void *), void *arg) { + uint64_t eflags; + void *stack = NULL; + + asm volatile("cli"); + LOG("Выделение потока\n"); + asm volatile("pushf"); + asm volatile("pop %0" : "=r"(eflags)); + task_t *new_task = mem_alloc(sizeof(task_t)); - LOG("new_task = 0x%x\n", new_task); - new_task->id = ++pid; - // mem_dump_memory( ); - LOG("Выделение состояния\n"); - new_task->state = mem_alloc(sizeof(struct frame)); + tool_memset(new_task, 0, sizeof(task_t)); + + new_task->id = next_thread_id++; + new_task->stack_size = STACK_SIZE; + new_task->entry_point = func; + + new_task->priority = 1; + + stack = mem_alloc(STACK_SIZE); + + new_task->stack = stack; + new_task->rsp = (uintptr_t)stack + STACK_SIZE - 16; + + uintptr_t *rsp = (uintptr_t *)stack; + *(--rsp) = (uintptr_t)func; // Добавляем entry_point на стек + *(--rsp) = eflags | (1 << 9); // Сохраняем флаги на стеке + + // Добавляем new_task в цепочку + if (last_task != NULL) { last_task->next = new_task; } + new_task->last = last_task; new_task->next = NULL; - - // Выделяем память под стек - LOG("Выделение стека\n"); - void *stack = mem_alloc(STACK_SIZE); - - // Устанавливаем значения регистров для нового потока - LOG("Установка регистров\n"); - new_task->state->rbp = (uint64_t)stack + STACK_SIZE; // Указываем на вершину стека - new_task->state->rbx = 0; - new_task->state->r15 = 0; - new_task->state->r14 = 0; - new_task->state->r13 = 0; - new_task->state->r12 = 0; - new_task->state->r11 = 0; - new_task->state->r10 = 0; - new_task->state->r9 = 0; - new_task->state->r8 = 0; - new_task->state->rax = 0; - new_task->state->rcx = 0; - new_task->state->rdx = 0; - new_task->state->rsi = 0; - new_task->state->rdi = (uint64_t)arg; // Передаем аргументы в регистр rdi - new_task->state->int_number = 0; - new_task->state->err = 0; - new_task->state->rip = (uint64_t)func; // Устанавливаем адрес функции - new_task->state->cs = 0; - new_task->state->rflags = 0; - new_task->state->rsp = (uint64_t)stack + STACK_SIZE; // Указываем на вершину стека - new_task->state->ss = 0; + last_task = new_task; if (kernel_task == NULL) { LOG("Ядро ID: %u\n", new_task->id); @@ -101,11 +91,29 @@ task_t *task_new_thread(void (*func)(void *), void *arg) { } LOG("Создан новый поток с ID: %u\n", new_task->id); + asm volatile("sti"); // Включаем прерывания return new_task; } void task_init( ) { + uint64_t rsp; + uint64_t cr3; + + asm volatile("mov %%rsp, %0" : "=r"(rsp)); + + asm volatile("mov %%cr3, %0" : "=r"(cr3)); + asm volatile("cli"); + + kernel_task = mem_alloc(sizeof(task_t)); + tool_memset(kernel_task, 0, sizeof(task_t)); + kernel_task->id = next_thread_id++; + kernel_task->stack_size = STACK_SIZE; + kernel_task->rsp = rsp; + + current_task = kernel_task; + last_task = kernel_task; + idt_set_int(32, task_switch); LOG("Потоки инициализированы\n"); } diff --git a/modules/imfs/build.sh b/modules/imfs/build.sh old mode 100644 new mode 100755 diff --git a/modules/tga/build.sh b/modules/tga/build.sh old mode 100644 new mode 100755