mirror of https://github.com/0Nera/BMOSP.git
Добавлено переключение потоков
This commit is contained in:
parent
9527feb839
commit
99b04b5481
|
@ -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 {
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 1
|
||||
#define VERSION_BUILD 945
|
||||
#define VERSION_BUILD 968
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
extern uint64_t full_init;
|
||||
|
||||
void task_switch_asm(task_t *, task_t *);
|
||||
|
||||
void task_switch(struct frame *state) {
|
||||
// Смена потоков
|
||||
UNUSED(state);
|
||||
|
||||
LOG("Смена потоков\n");
|
||||
asm volatile("cli");
|
||||
asm volatile("pushf");
|
||||
|
||||
task_t *prev_task = current_task;
|
||||
task_t *next = current_task->next;
|
||||
task_t *last = current_task;
|
||||
|
||||
if (current_task->next == NULL) { current_task = kernel_task; }
|
||||
current_task = next;
|
||||
|
||||
LOG("Смена потоков %u -> ", current_task->id);
|
||||
|
||||
asm volatile("mov %%rsp, %0" : "=a"(current_task->rsp));
|
||||
|
||||
current_task = current_task->next;
|
||||
|
||||
if (current_task == NULL) {
|
||||
// LOG("current_task == NULL\n");
|
||||
|
||||
// LOG("current_task = kernel_task\n");
|
||||
current_task = kernel_task;
|
||||
}
|
||||
|
||||
LOG("%u\n", current_task->id);
|
||||
|
||||
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;
|
||||
new_task->cr3 = cr3;
|
||||
new_task->id = next_thread_id++;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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"); // Включаем прерывания
|
||||
}
|
||||
|
||||
return new_task->id;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -15,6 +15,8 @@
|
|||
#include <tool.h>
|
||||
#include <version.h>
|
||||
|
||||
uint64_t full_init = 0;
|
||||
|
||||
// Точка входа
|
||||
void _start( ) {
|
||||
asm volatile("cli");
|
||||
|
@ -37,6 +39,8 @@ void _start( ) {
|
|||
|
||||
LOG("Готово! Для выхода из симуляции удерживайте: ESCAPE\n");
|
||||
|
||||
full_init = 1;
|
||||
|
||||
asm volatile("sti");
|
||||
|
||||
for (;;) { asm volatile("hlt"); }
|
||||
|
|
Loading…
Reference in New Issue