more userspace stuff

This commit is contained in:
2026-07-01 20:00:22 -05:00
parent af6c1c94cf
commit b6ee4fc3de
21 changed files with 161 additions and 121 deletions

View File

@@ -1,4 +1,5 @@
#include <lib/tasks.h>
#include <lib/print.h>
#include <lib/memory.h>
#include <memory/mm.h>
@@ -69,7 +70,9 @@ uint32_t switch_context(uint32_t current_esp) {
current_process = next_process;
tss.esp0 = process_table[current_process].esp0;
if (process_table[current_process].flags & PROCESS_FLAG_USER ) {
tss.esp0 = process_table[current_process].kstack_top;
}
if (fetch_cr3() != process_table[current_process].cr3) {
load_pd((void*)process_table[current_process].cr3);
@@ -88,14 +91,15 @@ void init_scheduler() {
process->cr3 = fetch_cr3();
process->state = STATE_READY;
process->sleep = 0;
process->flags = PROCESS_FLAG_KERNEL;
total_processes++;
create_task((uint32_t)idle_task, fetch_cr3(), 0);
create_task((uint32_t)idle_task, fetch_cr3(), 0, 0);
current_process = 0;
}
int create_task(uint32_t entry_point, uint32_t cr3, int user) {
int create_task(uint32_t entry_point, uint32_t cr3, int user, uint32_t u_esp) {
if (total_processes >= 16) {
return 0;
}
@@ -103,12 +107,14 @@ int create_task(uint32_t entry_point, uint32_t cr3, int user) {
lock_scheduler();
// default to a new task, but if we find a dead one, re use it
int reuse = 0;
process_t* process = &process_table[total_processes];
uint32_t pid = total_processes;
for (uint32_t i = 0; i < total_processes; i++) {
if (process_table[i].state == STATE_DEAD) {
process = &process_table[i];
pid = i;
reuse = 1;
}
}
@@ -116,22 +122,26 @@ int create_task(uint32_t entry_point, uint32_t cr3, int user) {
process->cr3 = cr3;
process->state = STATE_READY;
process->sleep = 0;
process->flags = user ? PROCESS_FLAG_USER : PROCESS_FLAG_KERNEL;
void* stack_bottom = kalloc(4096);
uint32_t* esp = (uint32_t*)((uint32_t)stack_bottom + 4096);
process->esp0 = (uint32_t)esp;
void* kstack_bottom = kalloc(PAGE_SIZE);
uint32_t kstack_top = (uint32_t)kstack_bottom + PAGE_SIZE;
process->kstack_top = kstack_top;
uint32_t* esp = (uint32_t*)kstack_top;
if (user) {
*(--esp) = 0x23; // User Data Segment (SS) with RPL 3 (0x20 | 3)
*(--esp) = 0xBFFFF000; // User Stack Pointer (ESP) - location mapped in user space
*(--esp) = u_esp; // User Stack Pointer (ESP) - location mapped in user space
*(--esp) = 0x0202; // EFLAGS (Interrupts enabled)
*(--esp) = 0x1B; // User Code Segment (CS) with RPL 3 (0x18 | 3)
*(--esp) = entry_point; // EIP
*(--esp) = 0x23;
} else {
// IRET values for Ring 0
*(--esp) = 0x0202; // EFLAGS
*(--esp) = 0x08; // Kernel Code Segment (CS)
*(--esp) = entry_point; // EIP
*(--esp) = 0x10;
}
*(--esp) = 0; // EAX
@@ -144,7 +154,9 @@ int create_task(uint32_t entry_point, uint32_t cr3, int user) {
*(--esp) = 0; // EDI
process->esp = (uint32_t)esp;
total_processes++;
if (!reuse) {
total_processes++;
}
unlock_scheduler();
return 1;
}