diff --git a/kernel/include/process.hpp b/kernel/include/process.hpp index 886e83fd..453cc83f 100644 --- a/kernel/include/process.hpp +++ b/kernel/include/process.hpp @@ -25,6 +25,9 @@ struct process_t { bool system; + uint16_t code_selector; + uint16_t data_selector; + size_t physical_cr3; size_t paging_size; diff --git a/kernel/include/scheduler.hpp b/kernel/include/scheduler.hpp index 213fc367..3738adaf 100644 --- a/kernel/include/scheduler.hpp +++ b/kernel/include/scheduler.hpp @@ -8,6 +8,8 @@ #ifndef SCHEDULER_H #define SCHEDULER_H +#include "process.hpp" + namespace scheduler { void init(); @@ -17,6 +19,9 @@ void kill_current_process(); void reschedule(); +process_t new_process(); +void queue_process(process_t&& p); + } //end of namespace scheduler #endif diff --git a/kernel/src/scheduler.cpp b/kernel/src/scheduler.cpp index bfb4305a..1289f9bd 100644 --- a/kernel/src/scheduler.cpp +++ b/kernel/src/scheduler.cpp @@ -6,9 +6,9 @@ //======================================================================= #include "scheduler.hpp" -#include "process.hpp" #include "paging.hpp" #include "assert.hpp" +#include "gdt.hpp" #include "console.hpp" @@ -46,6 +46,9 @@ void create_idle_task(){ idle_process.user_rsp = reinterpret_cast(&idle_stack[63]); idle_process.kernel_rsp = reinterpret_cast(&idle_kernel_stack[4095]); + idle_process.code_selector = gdt::LONG_SELECTOR; + idle_process.data_selector = gdt::DATA_SELECTOR; + processes.push_back(std::move(idle_process)); rounds.push_back(0); } @@ -55,7 +58,24 @@ void switch_to_process(size_t index){ k_printf("Switched to %u\n", index); - //TODO + //TODO Move that to scheduler + auto& process = processes[current_index]; + + gdt::tss.rsp0_low = process.kernel_rsp & 0xFFFFFFFF; + gdt::tss.rsp0_high = process.kernel_rsp >> 32; + + asm volatile("mov ax, %0; mov ds, ax; mov es, ax; mov fs, ax; mov gs, ax;" + : //No outputs + : "r" (process.data_selector) + : "rax"); + + asm volatile("mov cr3, %0" : : "r" (process.physical_cr3) : "memory"); + + //TODO Check if user_rsp is correctly passed + asm volatile("xor rax, rax; mov ax, %0; push rax; mov rax, %1; push rax; pushfq; xor rax, rax; mov ax, %2; push rax; mov rax, %3; push rax; iretq" + : //No outputs + : "r" (process.data_selector), "r" (process.user_rsp), "r" (process.code_selector), "r" (process.rip) + : "rax"); } size_t select_next_process(){ @@ -89,6 +109,8 @@ void scheduler::kill_current_process(){ } void scheduler::reschedule(){ + k_print_line("RS"); + //Test if the current process just got killed if(current_index == processes.size()){ current_index = 0; @@ -108,3 +130,17 @@ void scheduler::reschedule(){ //At this point we just have to return to the current process } + +scheduler::process_t scheduler::new_process(){ + process_t p; + + p.system = false; + p.pid = next_pid++; + + return std::move(p); +} + +void scheduler::queue_process(process_t&& p){ + processes.push_back(std::forward(p)); + rounds.push_back(0); +} diff --git a/kernel/src/shell.cpp b/kernel/src/shell.cpp index 12fe03a1..a1654aec 100644 --- a/kernel/src/shell.cpp +++ b/kernel/src/shell.cpp @@ -880,30 +880,24 @@ void exec_command(const std::vector& params){ auto buffer = content->c_str(); auto header = reinterpret_cast(buffer); - scheduler::process_t process; + auto process = scheduler::new_process(); if(!create_paging(buffer, process)){ k_print_line("Impossible to initialize paging"); return; } - gdt::tss.rsp0_low = scheduler::kernel_rsp & 0xFFFFFFFF; - gdt::tss.rsp0_high = scheduler::kernel_rsp >> 32; + process.kernel_rsp = scheduler::kernel_rsp; + process.user_rsp = scheduler::user_rsp; - asm volatile("mov ax, %0; mov ds, ax; mov es, ax; mov fs, ax; mov gs, ax;" - : //No outputs - : "i" (gdt::USER_DATA_SELECTOR + 3) - : "rax"); + process.rip = header->e_entry; - asm volatile("mov cr3, %0" : : "r" (process.physical_cr3) : "memory"); + process.code_selector = gdt::USER_CODE_SELECTOR + 3; + process.data_selector = gdt::USER_DATA_SELECTOR + 3; - //TODO Check if user_rsp is correctly passed - asm volatile("push %0; push %1; pushfq; push %2; push %3; iretq" - : //No outputs - : "i" (gdt::USER_DATA_SELECTOR + 3), "r" (scheduler::user_rsp), "i" (gdt::USER_CODE_SELECTOR + 3), "r" (header->e_entry) - : "rax"); + scheduler::queue_process(std::move(process)); - //TODO Release all physical memory + scheduler::start(); } void vesainfo_command(const std::vector&){