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:
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/* ========================= */
|
||||
|
||||
Reference in New Issue
Block a user