Working Scheduler and Kernel Threads
This commit is contained in:
parent
0e2cfab914
commit
c39cca3f18
|
|
@ -1,4 +1,4 @@
|
||||||
CFLAGS="-g -c -m32 -fno-pie -mno-sse -O3 -D __bits__=32 -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -Wno-incompatible-pointer-types -Wno-address-of-packed-member -fno-stack-protector -mno-red-zone -mno-sse -mno-sse2 -ffreestanding -nostdlib -mno-mmx"
|
CFLAGS="-g -c -m32 -fno-pie -mno-sse -O3 -D __bits__=32 -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -Wno-incompatible-pointer-types -Wno-address-of-packed-member -Wno-discarded-qualifiers -fno-stack-protector -mno-red-zone -mno-sse -mno-sse2 -ffreestanding -nostdlib -mno-mmx"
|
||||||
LDFLAGS_i386="-Ttext 0xc0000000 --oformat binary -melf_i386"
|
LDFLAGS_i386="-Ttext 0xc0000000 --oformat binary -melf_i386"
|
||||||
|
|
||||||
cd src/kernel/
|
cd src/kernel/
|
||||||
|
|
|
||||||
|
|
@ -344,7 +344,7 @@ _irq_common_stub:
|
||||||
push esp;push argument
|
push esp;push argument
|
||||||
call _irq_handler
|
call _irq_handler
|
||||||
pop esp
|
pop esp
|
||||||
|
mov esp, eax
|
||||||
pop gs
|
pop gs
|
||||||
pop fs
|
pop fs
|
||||||
pop es
|
pop es
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,8 @@ inline void set_idt_entry(uint32_t index, void *ptr, uint8_t flags, uint16_t seg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _irq_handler(cpu_registers_t *regs){
|
cpu_registers_t *_irq_handler(cpu_registers_t *regs){
|
||||||
|
regs->esp = (uint32_t)regs;
|
||||||
if(regs->int_no == 0x80){
|
if(regs->int_no == 0x80){
|
||||||
regs = syscall(regs);
|
regs = syscall(regs);
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +51,7 @@ void _irq_handler(cpu_registers_t *regs){
|
||||||
if(regs->int_no >= 0x28){
|
if(regs->int_no >= 0x28){
|
||||||
outb(0xa0, 0x20);
|
outb(0xa0, 0x20);
|
||||||
}
|
}
|
||||||
return;
|
return regs;
|
||||||
}
|
}
|
||||||
void _isr_handler(cpu_registers_t *regs){
|
void _isr_handler(cpu_registers_t *regs){
|
||||||
printf("Error!! %x\n", regs->eip);
|
printf("Error!! %x\n", regs->eip);
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,15 @@
|
||||||
#include "shared/interrupts.h"
|
#include "shared/interrupts.h"
|
||||||
#include "drivers/serial.h"
|
#include "drivers/serial.h"
|
||||||
#include "drivers/pic.h"
|
#include "drivers/pic.h"
|
||||||
|
#include "drivers/cpuio.h"
|
||||||
#include "system/scheduler.h"
|
#include "system/scheduler.h"
|
||||||
|
|
||||||
|
void test(){
|
||||||
|
printf("Hi from another thread!\n");
|
||||||
|
// *((uint16_t*)0xb8000) = 0xf41;
|
||||||
|
for(;;);
|
||||||
|
}
|
||||||
|
|
||||||
extern void kmain(kernel_info_t *kernel_info){
|
extern void kmain(kernel_info_t *kernel_info){
|
||||||
init_serial();
|
init_serial();
|
||||||
pm_init(kernel_info);
|
pm_init(kernel_info);
|
||||||
|
|
@ -16,6 +23,9 @@ extern void kmain(kernel_info_t *kernel_info){
|
||||||
pic_setmask(0xfe, PIC1_DATA);
|
pic_setmask(0xfe, PIC1_DATA);
|
||||||
enable_interrupts();
|
enable_interrupts();
|
||||||
// printf("done\n");
|
// printf("done\n");
|
||||||
|
thread_start(test, 0);
|
||||||
|
// printf("%x", test);
|
||||||
|
// void test();
|
||||||
for(;;);
|
for(;;);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -12,3 +12,4 @@ inline uint32_t strlen(char *str){
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
void strcpy(char *src, char *dest);
|
void strcpy(char *src, char *dest);
|
||||||
|
void memcpy(char *src, char *dest, uint32_t c);
|
||||||
|
|
@ -1,34 +1,63 @@
|
||||||
#include "../shared/interrupts.h"
|
#include "../shared/interrupts.h"
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
|
#include "../shared/string.h"
|
||||||
#include "../shared/kstdlib.h"
|
#include "../shared/kstdlib.h"
|
||||||
|
#include "../shared/memory.h"
|
||||||
|
|
||||||
process_t volatile processes[0x10000];
|
process_t volatile processes[0x10000];
|
||||||
uint32_t volatile process_queue[0x10000];
|
uint32_t volatile process_queue[0x10000];
|
||||||
|
uint32_t active_processes;
|
||||||
uint32_t volatile current_pid;
|
uint32_t volatile current_pid;
|
||||||
|
uint32_t volatile queue_length;
|
||||||
|
uint32_t volatile current_queue_index;
|
||||||
void init_scheduler(){
|
void init_scheduler(){
|
||||||
for(uint32_t i = 0; i < 0x10000; i++){
|
for(uint32_t i = 0; i < 0x10000; i++){
|
||||||
processes[i].flags.present = 0;
|
processes[i].flags.present = 0;
|
||||||
process_queue[i] = 0;
|
process_queue[i] = 0;
|
||||||
}
|
}
|
||||||
current_pid = 0;
|
current_pid = 0;
|
||||||
|
queue_length = 0;
|
||||||
|
current_queue_index = 0;
|
||||||
|
active_processes = 0;
|
||||||
install_irq_handler(schedule, 0);
|
install_irq_handler(schedule, 0);
|
||||||
printf("Installing scheduler");
|
// printf("Installing scheduler");
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu_registers_t *schedule(cpu_registers_t *regs){
|
cpu_registers_t *schedule(cpu_registers_t *regs){
|
||||||
uint32_t i = current_pid;
|
if(queue_length == 0){
|
||||||
// printf("Test");
|
return regs;
|
||||||
while(processes[process_queue[i]].flags.blocked){
|
|
||||||
i++;
|
|
||||||
if(i == current_pid) return regs;
|
|
||||||
if(i >= 0x10000) i = 0;
|
|
||||||
}
|
}
|
||||||
current_pid = i;
|
uint32_t i = current_queue_index;
|
||||||
return &(processes[i].cpuregs);
|
for(; i < queue_length; i++){
|
||||||
|
if(processes[process_queue[i%queue_length]].flags.blocked) continue;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
current_pid = process_queue[i];
|
||||||
|
// printf("\n%d", current_pid);
|
||||||
|
// *regs = processes[current_pid].cpuregs;
|
||||||
|
cpu_registers_t *newregs = (cpu_registers_t*)processes[current_pid].cpuregs.esp;
|
||||||
|
return newregs;
|
||||||
// return regs;
|
// return regs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add_process_queue(uint32_t pid){
|
||||||
|
process_queue[queue_length] = pid;
|
||||||
|
queue_length++;
|
||||||
|
}
|
||||||
|
void remove_process_queue(uint32_t pid){
|
||||||
|
uint32_t last_queue_index = queue_length-1;
|
||||||
|
uint32_t old_index = 0;
|
||||||
|
for(uint32_t i = 0; i < last_queue_index; i++){
|
||||||
|
if(process_queue[i] == pid){
|
||||||
|
old_index = i;
|
||||||
|
process_queue[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(old_index == last_queue_index) return;
|
||||||
|
process_queue[old_index] = process_queue[last_queue_index];
|
||||||
|
process_queue[last_queue_index] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void spawn_new_process(cpu_registers_t defaultregs, char **argv, uint32_t argc, void *cr3){
|
void spawn_new_process(cpu_registers_t defaultregs, char **argv, uint32_t argc, void *cr3){
|
||||||
uint32_t i = current_pid;
|
uint32_t i = current_pid;
|
||||||
while(processes[i].flags.present){
|
while(processes[i].flags.present){
|
||||||
|
|
@ -36,6 +65,9 @@ void spawn_new_process(cpu_registers_t defaultregs, char **argv, uint32_t argc,
|
||||||
if(i >= 0x10000) i = 0;
|
if(i >= 0x10000) i = 0;
|
||||||
if(i == current_pid) return;
|
if(i == current_pid) return;
|
||||||
}
|
}
|
||||||
|
i += !active_processes;
|
||||||
|
active_processes++;
|
||||||
|
// printf("Found %d", i);
|
||||||
process_t new_proc = {0};
|
process_t new_proc = {0};
|
||||||
new_proc.argc = argc;
|
new_proc.argc = argc;
|
||||||
new_proc.argv = argv;
|
new_proc.argv = argv;
|
||||||
|
|
@ -46,6 +78,8 @@ void spawn_new_process(cpu_registers_t defaultregs, char **argv, uint32_t argc,
|
||||||
new_proc.flags.cpu_lvl = 1;
|
new_proc.flags.cpu_lvl = 1;
|
||||||
new_proc.flags.priority = 0;
|
new_proc.flags.priority = 0;
|
||||||
new_proc.flags.system = processes[current_pid].flags.system;
|
new_proc.flags.system = processes[current_pid].flags.system;
|
||||||
|
processes[i] = new_proc;
|
||||||
|
add_process_queue(i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,7 +93,17 @@ void exit(){
|
||||||
|
|
||||||
}
|
}
|
||||||
void thread_start(void (*function)(), uint32_t *exit_code){
|
void thread_start(void (*function)(), uint32_t *exit_code){
|
||||||
|
cpu_registers_t regs = {0};
|
||||||
|
regs.cs = 0x10;
|
||||||
|
regs.ds = 0x18;
|
||||||
|
regs.es = 0x18;
|
||||||
|
regs.ss = 0x18;
|
||||||
|
// regs.ebp =
|
||||||
|
regs.esp = 0x7000 - sizeof(regs) + 8;
|
||||||
|
regs.ebp = regs.esp;
|
||||||
|
regs.eip = (uint32_t)function;
|
||||||
|
memcpy((char *)®s, (char*)regs.esp, sizeof(regs));
|
||||||
|
spawn_new_process(regs, 0, 0, (void *)0x10000);
|
||||||
}
|
}
|
||||||
void thread_join(uint32_t thread_id, uint32_t **exit_code){
|
void thread_join(uint32_t thread_id, uint32_t **exit_code){
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,3 +22,4 @@ typedef struct{
|
||||||
|
|
||||||
cpu_registers_t* schedule(cpu_registers_t *regs);
|
cpu_registers_t* schedule(cpu_registers_t *regs);
|
||||||
void init_scheduler();
|
void init_scheduler();
|
||||||
|
void thread_start(void (*function)(), uint32_t *exit_code);
|
||||||
|
|
@ -34,7 +34,11 @@ void itoa(int64_t data, char *res, uint8_t base){
|
||||||
res[0] += negative * '-';
|
res[0] += negative * '-';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
void memcpy(char *src, char *dest, uint32_t c){
|
||||||
|
for(uint32_t i = 0; i < c; i++){
|
||||||
|
dest[i] = src[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
void strcpy(char *src, char *dest){
|
void strcpy(char *src, char *dest){
|
||||||
if(src == 0 || dest == 0){
|
if(src == 0 || dest == 0){
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue