Skip to content

Commit

Permalink
Добавлено переключение потоков
Browse files Browse the repository at this point in the history
  • Loading branch information
0Nera committed Jan 20, 2024
1 parent 9527feb commit 99b04b5
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 90 deletions.
19 changes: 10 additions & 9 deletions include/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@
#define STACK_SIZE 8192 // 1MB

typedef struct task {
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; // Предыдущий поток
uint64_t rax, rbx, rcx, rdx;
uint64_t rsi, rdi, rsp, rbp;
uint64_t cr3;

uint64_t id;
uint64_t ret;
void *stack;

struct task *last;
struct task *next;
} __attribute__((packed)) task_t;

struct frame {
Expand Down
2 changes: 2 additions & 0 deletions include/tool.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <stdarg.h>
#include <stdint.h>

#define UNUSED(x) (void)(x)

#define abs(x) ((x) < 0 ? -(x) : (x))

#define assert(check) \
Expand Down
2 changes: 1 addition & 1 deletion include/version.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#define VERSION_MAJOR 0
#define VERSION_MINOR 1
#define VERSION_BUILD 945
#define VERSION_BUILD 968
26 changes: 15 additions & 11 deletions kernel/cpu/idt.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,24 @@ static void encode_idt_entry(uint8_t vector, void *handler, uint8_t flags) {
static void exception_handler(struct frame state) {
LOG("\nПОЛУЧЕНО ИСКЛЮЧЕНИЕ: %s\n", exception_names[state.int_number]);

LOG(" RAX=%x RBX=%x\n"
" RCX=%x RDX=%x\n"
" RSI=%x RDI=%x\n"
" RBP=%x RSP=%x\n"
" R08=%x R09=%x\n"
" R10=%x R11=%x\n"
" R12=%x R13=%x\n"
" R14=%x R15=%x\n"
" RIP=%x RFLAGS=%x\n"
" CS=%x SS=%x\n"
" ERR=%x INT=%u",
uint64_t cr3;
asm volatile("mov %%cr3, %0" : "=r"(cr3));

LOG("\tRAX=%x RBX=%x\n"
"\tRCX=%x RDX=%x\n"
"\tRSI=%x RDI=%x\n"
"\tRBP=%x RSP=%x\n"
"\tR08=%x R09=%x\n"
"\tR10=%x R11=%x\n"
"\tR12=%x R13=%x\n"
"\tR14=%x R15=%x\n"
"\tRIP=%x RFLAGS=%x\n"
"\tCS=%x SS=%x\n"
"\tERR=%x INT=%u\n",
state.rax, state.rbx, state.rcx, state.rdx, state.rsi, state.rdi, state.rbp, state.rsp, state.r8, state.r9,
state.r10, state.r11, state.r12, state.r13, state.r14, state.r15, state.rip, state.rflags, state.cs, state.ss,
state.err, state.int_number);
LOG("\tCR3=%x\n", cr3);

asm volatile("cli; hlt");
}
Expand Down
115 changes: 46 additions & 69 deletions kernel/cpu/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,123 +10,100 @@
#include <log.h>
#include <mem.h>

#if 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;
extern uint64_t full_init;

if (current_task->next == NULL) { current_task = kernel_task; }
void task_switch_asm(task_t *, task_t *);

LOG("Смена потоков %u -> ", current_task->id);

asm volatile("mov %%rsp, %0" : "=a"(current_task->rsp));

current_task = current_task->next;
void task_switch(struct frame *state) {
UNUSED(state);

if (current_task == NULL) {
// LOG("current_task == NULL\n");
LOG("Смена потоков\n");
asm volatile("cli");

// LOG("current_task = kernel_task\n");
current_task = kernel_task;
}
task_t *next = current_task->next;
task_t *last = current_task;

LOG("%u\n", current_task->id);
current_task = next;

asm volatile("mov %0, %%rsp" ::"a"(current_task->rsp));
asm volatile("popf");
LOG("Смена потоков 2\n");
task_switch_asm(last, next);
asm volatile("sti");
}

task_t *task_new_thread(void (*func)(void *), void *arg) {
uint64_t eflags;
void *stack = NULL;

uint64_t task_new_thread(void (*func)(void *), void *arg) {
asm volatile("cli");

LOG("Выделение потока\n");
uint64_t cr3;
asm volatile("mov %%cr3, %0" : "=r"(cr3));

asm volatile("pushf");
asm volatile("pop %0" : "=r"(eflags));

uint64_t *stack = mem_alloc(STACK_SIZE);
task_t *new_task = mem_alloc(sizeof(task_t));

tool_memset(stack, 0, STACK_SIZE);
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;
uint64_t *stack_top = (uint64_t *)((uint64_t)stack + STACK_SIZE);

new_task->priority = 1;
*(--stack_top) = (uint64_t)arg;
*(--stack_top) = (uint64_t)func;

stack = mem_alloc(STACK_SIZE);
new_task->rsp = (uint64_t)new_task->stack + STACK_SIZE - sizeof(uint64_t) * 2;

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;
last_task = new_task;

if (kernel_task == NULL) {
LOG("Ядро ID: %u\n", new_task->id);
kernel_task = new_task;
current_task = new_task;
}
new_task->cr3 = cr3;
new_task->id = next_thread_id++;

if (current_task != new_task) {
LOG("Прошлый ID: %u\n", current_task->id);
current_task->next = new_task;
}
new_task->last = current_task;
new_task->next = current_task->next;
current_task->next->last = new_task;
current_task->next = new_task;

LOG("Создан новый поток с ID: %u\n", new_task->id);
asm volatile("sti"); // Включаем прерывания

return new_task;
}
if (full_init) {
asm volatile("sti"); // Включаем прерывания
}

#endif
return new_task->id;
}

void notask_switch( ) {
asm volatile("nop");
void dummy(uint64_t n) {
for (;;) {
asm volatile("hlt");
}
}

void task_init( ) {
LOG("Потоки не инициализированы\n");
idt_set_int(32, notask_switch);
asm volatile("cli");
idt_set_int(32, task_switch);

#if 0
return;
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->cr3 = cr3;
kernel_task->rsp = rsp;

current_task = kernel_task;

current_task->last = current_task;
current_task->next = current_task;

last_task = kernel_task;

task_new_thread(dummy, 2 + 2);

LOG("Потоки инициализированы\n");
#endif
}
27 changes: 27 additions & 0 deletions kernel/cpu/task_switch.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.global task_switch_asm
task_switch_asm:
pushfq
movq %rax, (%rdi)
movq %rbx, 8(%rdi)
movq %rcx, 16(%rdi)
movq %rdx, 24(%rdi)
movq %rsi, 32(%rdi)
movq %rdi, 40(%rdi)
movq %rsp, 48(%rdi)
movq %rbp, 56(%rdi)
movq %cr3, %rax
movq %rax, 64(%rdi)

movq 64(%rsi), %rax
movq %rax, %cr3
movq 56(%rsi), %rbp
movq 48(%rsi), %rsp
movq 40(%rsi), %rdi
movq 24(%rsi), %rdx
movq 16(%rsi), %rcx
movq 8(%rsi), %rbx
movq (%rsi), %rax
movq 32(%rsi), %rsi
popfq

retq
4 changes: 4 additions & 0 deletions kernel/start.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <tool.h>
#include <version.h>

uint64_t full_init = 0;

// Точка входа
void _start( ) {
asm volatile("cli");
Expand All @@ -37,6 +39,8 @@ void _start( ) {

LOG("Готово! Для выхода из симуляции удерживайте: ESCAPE\n");

full_init = 1;

asm volatile("sti");

for (;;) { asm volatile("hlt"); }
Expand Down

0 comments on commit 99b04b5

Please sign in to comment.