Files
KatauOS/src/tasking/task.c
T

158 lines
3.6 KiB
C

#include "../include/task.h"
#include "../include/stdio.h"
#include "../include/paging.h"
#include "../include/string.h"
#include <stddef.h>
Process* current = 0;
Process* queue = 0;
uint32_t irq_disable_counter = 0;
uint32_t pid_counter;
uint32_t task_count;
#define KSTACKSIZE 4096
#define USTACKSIZE 4096
extern void trapret(void);
extern void switchProcess(Process* next);
extern Process* queue;
extern Process* current;
extern uint32_t pid_counter;
extern uint32_t task_count;
Process* task_create(uint32_t func, uint32_t user_esp, uint32_t ring, uint32_t* pagedir)
{
void *p_physical = alloc_page();
Process* p = (Process*)((uint32_t)p_physical+0xC0000000);
map_page(p_physical, (void*)p, PAGE_PRESENT | PAGE_RW);
memset(p, 0, sizeof(Process));
p->pid = ++pid_counter;
p->state = Ready;
p->ring = ring;
// Выделяем стек ядра
void *kstack_physical = alloc_page();
p->kstack = (char*)((uint32_t)kstack_physical+0xC0000000);
map_page(kstack_physical, p->kstack, PAGE_PRESENT | PAGE_RW);
debug_log("kstack: %X!!!!!!!!!!!!\n", p->kstack);
uint8_t* sp = (uint8_t*)(p->kstack + KSTACKSIZE);
sp -= sizeof(TrapFrame);
p->tf = (TrapFrame*)sp;
memset(p->tf, 0, sizeof(TrapFrame));
p->tf->cs = ring == 3 ? (SEG_UCODE | DPL_USER) : (SEG_KCODE);
p->tf->ds = ring == 3 ? (SEG_UDATA | DPL_USER) : (SEG_KDATA);
p->tf->es = p->tf->ds;
p->tf->fs = p->tf->ds;
p->tf->gs = p->tf->ds;
p->tf->usermode_ss = ring == 3 ? (SEG_UDATA | DPL_USER) : (SEG_KDATA);
p->tf->eflags = FL_IF;
p->tf->eip = (uint32_t)func;
p->pagedir = pagedir;//(uint32_t*)create_page_dir();
if(ring == 3)
{
/*void* user_stack_physical = alloc_page();
uint32_t user_stack_virtual_top = 0xBFFFF000 - ((p->pid -1) * (USTACKSIZE + 4096)); // Уникальный верх стека для каждого процесса
uint32_t user_stack_virtual_base = user_stack_virtual_top - USTACKSIZE;
map_page_in_directory(p->pagedir, user_stack_physical, (void*)user_stack_virtual_base, PAGE_PRESENT | PAGE_RW | PAGE_USER); // Флаги 0x7
*/
p->tf->usermode_esp = user_esp;//user_stack_virtual_top;
}
sp -= sizeof(Context);
p->context = (Context*)sp;
memset(p->context, 0, sizeof(Context));
p->context->eip = (uint32_t)trapret;
p->kesp = (uint32_t)sp;
p->next = 0;
if (!queue) {
queue = p;
current = queue;
} else {
Process* curr = queue;
while (curr->next)
curr = curr->next;
curr->next = p;
}
task_count++;
return p;
}
// Остальные функции остаются без изменений
void scheduler_lock()
{
asm volatile("cli");
irq_disable_counter++;
}
void scheduler_unlock()
{
irq_disable_counter--;
if (irq_disable_counter == 0)
asm volatile("sti");
}
void schedule()
{
if (!current)
return;
Process* next = current->next;
if (!next)
next = queue;
if (next != current)
{
switchProcess(next);
}
}
void idle()
{
while (1) {}
}
void task1()
{
while (1) {
printf("task1\n");
}
}
void task2()
{
int a = 0;
while (1) { a++; printf("task2 %X\n", a); }
}
void jump_usermode2(void) ;
void scheduler_init()
{
uint32_t* kernel_tasks_pagedir = (uint32_t*)create_page_dir();
task_create((uint32_t)idle, 0, 0, kernel_tasks_pagedir);
}
void handle_syscall(TrapFrame *tf)
{
debug_log("EAX: %X ", tf->eax);
debug_log("EBX: %X ", tf->ebx);
debug_log("ECX: %s ", tf->ecx);
debug_log("EDX: %X\n", tf->edx);
}