sched: Implement basic scheduling and signal handling system

Note: this is probably 25% broken, but it works right now as written, so I hope it all works.

- Added a new scheduler header file (scheduler.h) defining task structures, scheduling policies, and signal handling mechanisms.
- Integrated scheduling functions into the syscall interface, including SYS_GETPID, SYS_GETPPID, SYS_EXIT, SYS_SCHED_YIELD, SYS_NICE, SYS_KILL, SYS_SIGACTION, SYS_SIGPROCMASK, SYS_SCHED_GETSCHEDULER, and SYS_SCHED_SETSCHEDULER.
- Updated syscall handler to manage new scheduling-related syscalls and signal actions.

Signed-off-by: kaguya <vpshinomiya@protonmail.com>
This commit is contained in:
kaguya
2026-04-26 22:46:28 -04:00
parent 336af1c2ad
commit 7d99745ff9
20 changed files with 1561 additions and 53 deletions
+48 -19
View File
@@ -5,24 +5,53 @@
#include "mm/memory.h"
#include "libk/stdio.h"
#include "fs/elf.h"
#include "sched/scheduler.h"
extern uintptr_t g_hhdm_offset;
#define USER_STACK_TOP 0x00007FFFFFFFE000ULL
#define USER_STACK_PAGES 4
#define USER_STACK_PAGES 8
#define USER_STACK_SIZE (USER_STACK_PAGES * PAGE_SIZE)
#define PTE_PRESENT (1ULL << 0)
#define PTE_WRITABLE (1ULL << 1)
#define PTE_USER (1ULL << 2)
static uint64_t user_stack_phys_base = 0;
extern struct pagemap *kernel_pagemap;
//extern struct pagemap *kernel_pagemap;
uintptr_t setup_user_stack(void)
struct pagemap *create_user_pagemap(void)
{
struct pagemap *pm = kmalloc(sizeof(struct pagemap));
if (!pm) {
printf("Failed to allocate user pagemap struct!\n");
return NULL;
}
spinlock_init(&pm->lock);
/* Allocate a fresh PML4 (physical page) */
pm->top_level = (uint64_t *)((uintptr_t)pmm_allocz(1) + MEM_PHYS_OFFSET);
if (!pm->top_level) {
printf("Failed to allocate user PML4!\n");
kfree(pm);
return NULL;
}
/* Copy kernel higher-half mappings (kernel + HHDM) */
for (size_t i = 256; i < 512; i++) {
pm->top_level[i] = kernel_pagemap->top_level[i];
}
/* Lower half remains zero (user address space) */
printf("[usermode] user pagemap created (PML4 phys = 0x%lx)\n",
(uint64_t)pm->top_level - MEM_PHYS_OFFSET);
return pm;
}
uintptr_t setup_user_stack(struct pagemap *pagemap)
{
user_stack_phys_base = (uint64_t)pmm_alloc(USER_STACK_PAGES);
@@ -37,7 +66,7 @@ uintptr_t setup_user_stack(void)
uintptr_t virt = stack_bottom + i * PAGE_SIZE;
uintptr_t phys = user_stack_phys_base + i * PAGE_SIZE;
if (!vmm_map_page(kernel_pagemap,
if (!vmm_map_page(pagemap,
virt,
phys,
PAGE_READ | PAGE_WRITE | PAGE_USER,
@@ -47,19 +76,13 @@ uintptr_t setup_user_stack(void)
for (;;);
}
// zero physical page through HHDM
//memset((void *)(phys + g_hhdm_offset), 0, PAGE_SIZE);
}
uintptr_t rsp = USER_STACK_TOP;
rsp &= ~0xFULL;
return rsp;
}
// usermode.c
__attribute__((naked))
void enter_user_mode(uint64_t rip, uint64_t rsp)
{
@@ -98,21 +121,27 @@ void enter_user_mode(uint64_t rip, uint64_t rsp)
void start_userspace(void)
{
void *entry = NULL;
if (!ELF_Read("init.elf", &entry)) {
struct pagemap *user_pagemap = create_user_pagemap();
if (!user_pagemap) {
printf("Failed to create user pagemap\n");
for (;;);
}
void *elf_entry = NULL;
if (!ELF_Read("init.elf", &elf_entry, user_pagemap)) {
printf("Failed to load init.elf\n");
for(;;);
}
if (!entry) {
if (!elf_entry) {
printf("ELF has no entry point\n");
for(;;);
}
uintptr_t rsp = setup_user_stack();
uintptr_t user_rsp = setup_user_stack(user_pagemap);
printf("Entering usermode RIP=%p RSP=%p\n", entry, (void*)rsp);
printf("Entering usermode RIP=%p RSP=%p\n", elf_entry, (void*)user_rsp);
enter_user_mode((uint64_t)entry, (rsp & ~0xFULL));
sched_create_user_task("init", (uint64_t)elf_entry, user_rsp, user_pagemap);
}
+2 -1
View File
@@ -6,6 +6,7 @@
#include "e9.h"
#include "limine.h"
#include "apic.h"
#include "sched/scheduler.h"
__attribute__((used, section(".limine_requests")))
volatile struct limine_date_at_boot_request boot_request = {
@@ -39,7 +40,7 @@ void PIT_IRQ_Handler(Registers* regs)
lapic_eoi();
}
// You can add scheduler / time logic here later
sched_tick();
}
/* ========================= */