Move switching stuff to the scheduler

This commit is contained in:
Baptiste Wicht 2014-01-26 19:27:38 +01:00
parent 342d40c6f4
commit 5f88766c83
4 changed files with 54 additions and 16 deletions

View File

@ -25,6 +25,9 @@ struct process_t {
bool system; bool system;
uint16_t code_selector;
uint16_t data_selector;
size_t physical_cr3; size_t physical_cr3;
size_t paging_size; size_t paging_size;

View File

@ -8,6 +8,8 @@
#ifndef SCHEDULER_H #ifndef SCHEDULER_H
#define SCHEDULER_H #define SCHEDULER_H
#include "process.hpp"
namespace scheduler { namespace scheduler {
void init(); void init();
@ -17,6 +19,9 @@ void kill_current_process();
void reschedule(); void reschedule();
process_t new_process();
void queue_process(process_t&& p);
} //end of namespace scheduler } //end of namespace scheduler
#endif #endif

View File

@ -6,9 +6,9 @@
//======================================================================= //=======================================================================
#include "scheduler.hpp" #include "scheduler.hpp"
#include "process.hpp"
#include "paging.hpp" #include "paging.hpp"
#include "assert.hpp" #include "assert.hpp"
#include "gdt.hpp"
#include "console.hpp" #include "console.hpp"
@ -46,6 +46,9 @@ void create_idle_task(){
idle_process.user_rsp = reinterpret_cast<size_t>(&idle_stack[63]); idle_process.user_rsp = reinterpret_cast<size_t>(&idle_stack[63]);
idle_process.kernel_rsp = reinterpret_cast<size_t>(&idle_kernel_stack[4095]); idle_process.kernel_rsp = reinterpret_cast<size_t>(&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)); processes.push_back(std::move(idle_process));
rounds.push_back(0); rounds.push_back(0);
} }
@ -55,7 +58,24 @@ void switch_to_process(size_t index){
k_printf("Switched to %u\n", 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(){ size_t select_next_process(){
@ -89,6 +109,8 @@ void scheduler::kill_current_process(){
} }
void scheduler::reschedule(){ void scheduler::reschedule(){
k_print_line("RS");
//Test if the current process just got killed //Test if the current process just got killed
if(current_index == processes.size()){ if(current_index == processes.size()){
current_index = 0; current_index = 0;
@ -108,3 +130,17 @@ void scheduler::reschedule(){
//At this point we just have to return to the current process //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<scheduler::process_t>(p));
rounds.push_back(0);
}

View File

@ -880,30 +880,24 @@ void exec_command(const std::vector<std::string>& params){
auto buffer = content->c_str(); auto buffer = content->c_str();
auto header = reinterpret_cast<elf::elf_header*>(buffer); auto header = reinterpret_cast<elf::elf_header*>(buffer);
scheduler::process_t process; auto process = scheduler::new_process();
if(!create_paging(buffer, process)){ if(!create_paging(buffer, process)){
k_print_line("Impossible to initialize paging"); k_print_line("Impossible to initialize paging");
return; return;
} }
gdt::tss.rsp0_low = scheduler::kernel_rsp & 0xFFFFFFFF; process.kernel_rsp = scheduler::kernel_rsp;
gdt::tss.rsp0_high = scheduler::kernel_rsp >> 32; process.user_rsp = scheduler::user_rsp;
asm volatile("mov ax, %0; mov ds, ax; mov es, ax; mov fs, ax; mov gs, ax;" process.rip = header->e_entry;
: //No outputs
: "i" (gdt::USER_DATA_SELECTOR + 3)
: "rax");
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 scheduler::queue_process(std::move(process));
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");
//TODO Release all physical memory scheduler::start();
} }
void vesainfo_command(const std::vector<std::string>&){ void vesainfo_command(const std::vector<std::string>&){