From 7bb542d9013bb491f6b9c235a111f582c37fb864 Mon Sep 17 00:00:00 2001 From: xamidev Date: Mon, 2 Feb 2026 11:05:27 +0100 Subject: [PATCH] bump-allocated PID but kheap needs fix to kmalloc more than PAGE_SIZE --- src/kmain.c | 25 +++++++++++++++++------- src/mem/heap/kheap.c | 9 +++++++++ src/mem/heap/kheap.h | 1 + src/sched/process.c | 29 +++++++++++++++++++++++++--- src/sched/process.h | 10 +++++++++- src/sched/scheduler.c | 45 ++++++++++++++++++++++++------------------- src/string/string.c | 7 +++++++ src/string/string.h | 1 + 8 files changed, 96 insertions(+), 31 deletions(-) diff --git a/src/kmain.c b/src/kmain.c index 4874f7f..aeb02fd 100644 --- a/src/kmain.c +++ b/src/kmain.c @@ -82,6 +82,21 @@ struct boot_context boot_ctx; extern struct process_t* processes_list; extern struct process_t* current_process; +void pedicel_main(void* arg) +{ + +} + +void two_main(void* arg) +{ + +} + +void three_main(void* arg) +{ + +} + // This is our entry point void kmain() { @@ -118,13 +133,9 @@ void kmain() vmm_init(); - struct process_t* pedicel = process_create(); - struct process_t* two = process_create(); - struct process_t* three = process_create(); - - process_add(&processes_list, pedicel); - process_add(&processes_list, two); - process_add(&processes_list, three); + struct process_t* pedicel = process_create("pedicel", (void*)pedicel_main, 0); + struct process_t* two = process_create("two", (void*)two_main, 0); + struct process_t* three = process_create("three", (void*)three_main, 0); process_display_list(processes_list); scheduler_init(); diff --git a/src/mem/heap/kheap.c b/src/mem/heap/kheap.c index aff1f48..493f4e6 100644 --- a/src/mem/heap/kheap.c +++ b/src/mem/heap/kheap.c @@ -3,6 +3,7 @@ #include "mem/paging/pmm.h" #include #include +#include "sched/process.h" extern uint64_t kernel_phys_base; extern uint64_t kernel_virt_base; @@ -103,4 +104,12 @@ void kfree(void* ptr) // Set it free! struct heap_block_t* block = (struct heap_block_t*)((uintptr_t)ptr - sizeof(struct heap_block_t)); block->free = true; +} + +// Should alloc enough for a stack (at least 64kb) to be used for a process. +// Should return a pointer to top of the stack (as stack grows DOWNWARDS) +void* kalloc_stack() +{ + void* ptr = kmalloc(PROCESS_STACK_SIZE); + return ptr+PROCESS_STACK_SIZE; } \ No newline at end of file diff --git a/src/mem/heap/kheap.h b/src/mem/heap/kheap.h index f8bb8b5..2576c59 100644 --- a/src/mem/heap/kheap.h +++ b/src/mem/heap/kheap.h @@ -22,5 +22,6 @@ struct heap_block_t void kheap_init(); void* kmalloc(size_t size); void kfree(void* ptr); +void* kalloc_stack(); #endif \ No newline at end of file diff --git a/src/sched/process.c b/src/sched/process.c index 574de44..e8e8201 100644 --- a/src/sched/process.c +++ b/src/sched/process.c @@ -2,10 +2,14 @@ #include "process.h" #include "mem/heap/kheap.h" #include "kernel.h" +#include "string/string.h" +#include "mem/gdt/gdt.h" struct process_t* processes_list; struct process_t* current_process; +size_t next_free_pid = 0; + void process_init() { processes_list = NULL; @@ -26,16 +30,35 @@ void process_display_list(struct process_t* processes_list) DEBUG("NULL"); } -struct process_t* process_create() +struct process_t* process_create(char* name, void(*function)(void*), void* arg) { + CLEAR_INTERRUPTS; struct process_t* proc = (struct process_t*)kmalloc(sizeof(struct process_t)); + struct cpu_status_t* ctx = (struct cpu_status_t*)kmalloc(sizeof(struct cpu_status_t)); + + // No more memory? if (!proc) return NULL; + if (!ctx) return NULL; - proc->context = NULL; + strncpy(proc->name, name, PROCESS_NAME_MAX); + proc->pid = next_free_pid++; proc->status = READY; - proc->next = NULL; + 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_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->next = 0; + + process_add(&processes_list, proc); + + SET_INTERRUPTS; return proc; } diff --git a/src/sched/process.h b/src/sched/process.h index b23249b..c60f838 100644 --- a/src/sched/process.h +++ b/src/sched/process.h @@ -1,6 +1,8 @@ #ifndef PROCESS_H #define PROCESS_H +#include + typedef enum { READY, @@ -8,15 +10,21 @@ typedef enum DEAD } status_t; +#define PROCESS_NAME_MAX 64 +#define PROCESS_STACK_SIZE 0x100 // 64kb + struct process_t { + size_t pid; + char name[PROCESS_NAME_MAX]; + status_t status; struct cpu_status_t* context; struct process_t* next; }; void process_init(); -struct process_t* process_create(); +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); diff --git a/src/sched/scheduler.c b/src/sched/scheduler.c index 6bf3a39..6a94bf0 100644 --- a/src/sched/scheduler.c +++ b/src/sched/scheduler.c @@ -4,32 +4,37 @@ extern struct process_t* processes_list; extern struct process_t* current_process; -// DEBUG: how many times we did schedule -int scheduled = 0; - void scheduler_init() { // Choose first process? current_process = processes_list; } -void scheduler_schedule() +struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context) { - //DEBUG("Scheduler called!"); - if (current_process->next != NULL) - { - current_process = current_process->next; - } else - { - current_process = processes_list; - } - scheduled++; - DEBUG("SCHEDULER CALLED: current_process=%p", current_process); + current_process->context = context; + current_process->status = READY; - // debug - /* if (scheduled == 5) - { - DEBUG("enough, halting"); - hcf(); - } */ + for (;;) { + struct process_t* prev_process = current_process; + if (current_process->next != NULL) + { + current_process = current_process->next; + } else + { + current_process = processes_list; + } + + if (current_process != NULL && current_process->status == DEAD) + { + process_delete(&prev_process, current_process); + } else + { + current_process->status = RUNNING; + break; + } + } + + DEBUG("SCHEDULER CALLED: current_process=%p", current_process); + return current_process->context; } \ No newline at end of file diff --git a/src/string/string.c b/src/string/string.c index 0d63d14..0d52028 100644 --- a/src/string/string.c +++ b/src/string/string.c @@ -16,4 +16,11 @@ char *strcat(char *dest, const char *src){ dest[i+j] = src[j]; dest[i+j] = '\0'; return dest; +} + +// https://stackoverflow.com/questions/14159625/implementation-of-strncpy +void strncpy(char* dst, const char* src, size_t n) +{ + size_t i = 0; + while(i++ != n && (*dst++ = *src++)); } \ No newline at end of file diff --git a/src/string/string.h b/src/string/string.h index 1c0306e..7e9d8a5 100644 --- a/src/string/string.h +++ b/src/string/string.h @@ -3,5 +3,6 @@ char *strcpy(char *dest, const char *src); char *strcat(char *dest, const char *src); +void strncpy(char* dst, const char* src, size_t n); #endif \ No newline at end of file