Setup kernel stack; but process is failing

This commit is contained in:
2026-02-17 23:01:32 +01:00
parent 458ba375f3
commit ac7216d84a
15 changed files with 136 additions and 21 deletions

View File

@@ -11,10 +11,13 @@
#include "string/string.h"
#include "mem/gdt/gdt.h"
#include "config.h"
#include "io/serial/serial.h"
struct process_t* processes_list;
struct process_t* current_process;
extern uint64_t *kernel_pml4;
size_t next_free_pid = 0;
void process_init()
@@ -52,14 +55,22 @@ struct process_t* process_create(char* name, void(*function)(void*), void* arg)
proc->pid = next_free_pid++;
proc->status = READY;
uint64_t* stack_top = (uint64_t*)kalloc_stack();
// push return address to the stack so when "ret" hits we jmp to exit instead of idk what
// stack grows DOWNWARDS!!
*(--stack_top) = (uint64_t)process_exit;
proc->context = ctx;
proc->context->iret_ss = KERNEL_DATA_SEGMENT; // process will live in kernel mode
proc->context->iret_rsp = (uint64_t)kalloc_stack();
proc->context->iret_rsp = (uint64_t)stack_top;
proc->context->iret_flags = 0x202; //bit 2 and 9 set (Interrupt Flag)
proc->context->iret_cs = KERNEL_CODE_SEGMENT;
proc->context->iret_rip = (uint64_t)function; // beginning of executable code
proc->context->rdi = (uint64_t)arg; // 1st arg is in rdi (as per x64 calling convention)
proc->context->rbp = 0;
proc->context->rbp = 0;
// Kernel PML4 as it already maps code/stack (when switching to userland we'll have to change that)
proc->root_page_table = kernel_pml4;
proc->next = 0;
@@ -126,4 +137,38 @@ struct process_t* process_get_next(struct process_t* process)
{
if (!process) return NULL;
return process->next;
}
// (from gdt) This will switch tasks ONLY in ring 0
// KERNEL CS = 0x08
// KERNEL SS = 0x10
__attribute__((naked, noreturn))
void process_switch(uint64_t stack_addr, uint64_t code_addr)
{
asm volatile(" \
push $0x10 \n\
push %0 \n\
push $0x202 \n\
push $0x08 \n\
push %1 \n\
iretq \n\
" :: "r"(stack_addr), "r"(code_addr));
}
// Will be used to clean up resources (if any, when we implement it)
// Just mark as DEAD then idle. Scheduler will delete process at next timer interrupt % quantum.
void process_exit()
{
CLEAR_INTERRUPTS;
if (current_process)
{
current_process->status = DEAD;
}
SET_INTERRUPTS;
for (;;)
{
asm("hlt");
}
}

View File

@@ -9,6 +9,7 @@
#include <stddef.h>
#include "config.h"
#include <stdint.h>
typedef enum
{
@@ -33,6 +34,8 @@ struct process_t* process_create(char* name, void(*function)(void*), void* arg);
void process_add(struct process_t** processes_list, struct process_t* process);
void process_delete(struct process_t** processes_list, struct process_t* process);
struct process_t* process_get_next(struct process_t* process);
void process_switch(uint64_t stack_addr, uint64_t code_addr);
void process_exit();
void process_display_list(struct process_t* processes_list);

View File

@@ -6,6 +6,8 @@
#include "kernel.h"
#include "process.h"
#include "mem/paging/paging.h"
#include <stdint.h>
extern struct process_t* processes_list;
extern struct process_t* current_process;
@@ -18,7 +20,7 @@ void scheduler_init()
struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context)
{
current_process->context = context;
//current_process->context = context;
current_process->status = READY;
for (;;) {
@@ -41,6 +43,13 @@ struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context)
}
}
DEBUG("current_process={pid=%u name='%s'}", current_process->pid, current_process->name);
// Current_process gets wrong context?? (iret_rip points to other stuff than process function; like putpixel() for example)
DEBUG("current_process={pid=%u, name='%s', root_page_table[virt]=%p}", current_process->pid, current_process->name, current_process->root_page_table);
load_cr3(VIRT_TO_PHYS((uint64_t)current_process->root_page_table));
DEBUG("loaded process pml4 into cr3");
/* process_switch(current_process->context->rbp, current_process->context->iret_rip);
DEBUG("switched to process rip!"); */
return current_process->context;
}

View File

@@ -7,7 +7,7 @@
#ifndef SCHEDULER_H
#define SCHEDULER_H
void scheduler_schedule();
struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context);
void scheduler_init();
#endif