Hello user process

This commit is contained in:
2025-09-01 23:22:47 +02:00
parent 13ab117b1b
commit 2015e0e0aa
28 changed files with 744 additions and 65 deletions

View File

@ -1,5 +1,6 @@
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include "hal/hal.h"
#include "vmm/vmm.h"
#include "spinlock/spinlock.h"
@ -8,6 +9,10 @@
#include "pmm/pmm.h"
#include "util/util.h"
#include "kprintf.h"
#include "elf.h"
#include "errors.h"
#include "vfs/vfs.h"
#include "bootinfo/bootinfo.h"
#define PROC_REAPER_FREQ 30
@ -22,7 +27,66 @@ uint64_t sched_ticks = 0;
Procs PROCS;
bool proc_checkelf(uint8_t *elf) {
if (elf[0] != 0x7f || elf[1] != 'E' || elf[2] != 'L' || elf[3] != 'F') {
return false;
}
return true;
}
ElfAuxval proc_load_elf_segs(Proc *proc, uint8_t *data) {
#if defined(__x86_64__)
PgTable *vas = proc->platformdata.cr3;
#endif
ElfAuxval aux = {0};
Elf64_Ehdr *elfhdr = (Elf64_Ehdr *)data;
aux.entry = elfhdr->e_entry;
aux.phnum = elfhdr->e_phnum;
aux.phent = elfhdr->e_phentsize;
for (uint64_t seg = 0; seg < elfhdr->e_phnum; seg++) {
Elf64_Phdr *phdr = (Elf64_Phdr *)(data + elfhdr->e_phoff + (elfhdr->e_phentsize * seg));
switch (phdr->p_type) {
case PT_PHDR: {
aux.phdr = (uint64_t)phdr->p_vaddr;
} break;
case PT_LOAD: {
uint64_t off = phdr->p_vaddr & (HAL_PAGE_SIZE - 1);
uint64_t blocks = (phdr->p_memsz / HAL_PAGE_SIZE) + 1;
uint8_t *physaddr = pmm_alloc(blocks);
uint8_t *virtaddr = (uint8_t *)(phdr->p_vaddr - off);
hal_memset(VIRT(physaddr), 0, phdr->p_memsz);
hal_memcpy(VIRT(physaddr) + off, (data + phdr->p_offset), phdr->p_filesz);
#if defined(__x86_64__)
uint32_t pgflags = HAL_PG_USER | HAL_PG_RW | HAL_PG_PRESENT;
hal_vmm_map_range(VIRT(vas), virtaddr, physaddr, blocks * HAL_PAGE_SIZE, pgflags);
#endif
VasRange *range = dlmalloc(sizeof(*range));
range->virtstart = virtaddr;
range->physstart = physaddr;
range->size = blocks * HAL_PAGE_SIZE;
#if defined(__x86_64__)
range->pgflags = pgflags;
#endif
LL_APPEND(proc->vas, range);
} break;
}
}
return aux;
}
Proc *proc_spawnkern(void (*ent)(void), char *name) {
if (pids >= PROC_MAX) {
return NULL;
}
Proc *proc = dlmalloc(sizeof(*proc));
if (proc == NULL) {
return NULL;
@ -51,6 +115,56 @@ Proc *proc_spawnkern(void (*ent)(void), char *name) {
return proc;
}
Proc *proc_spawnuser(char *mountpoint, char *path) {
VfsStat stat;
if (vfs_stat(mountpoint, path, &stat) != E_OK) {
return NULL;
}
if (stat.type != VFS_TYPE_FILE) {
return NULL;
}
uint8_t *data = dlmalloc(stat.size);
if (vfs_read(mountpoint, path, data, stat.size, 0) != E_OK) {
return NULL;
}
Proc *proc = dlmalloc(sizeof(*proc));
hal_memset(proc, 0, sizeof(*proc));
ksprintf(proc->name, "%s:%s", mountpoint, path);
uint8_t *sp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS) + PROC_STACKSIZE;
uint8_t *spbase = sp - PROC_STACKSIZE;
#if defined(__x86_64__)
proc->platformdata.kstack = sp;
hal_memset(&proc->platformdata.trapframe, 0, sizeof(proc->platformdata.trapframe));
proc->platformdata.cr3 = hal_vmm_userproc_pml4(proc);
uint32_t flags = HAL_PG_RW | HAL_PG_USER | HAL_PG_PRESENT;
hal_vmm_map_range(VIRT(proc->platformdata.cr3), spbase, spbase, PROC_STACKSIZE, flags);
VasRange *range = dlmalloc(sizeof(*range));
range->virtstart = spbase;
range->physstart = spbase;
range->size = PROC_STACKSIZE;
range->pgflags = flags;
LL_APPEND(proc->vas, range);
ElfAuxval aux = proc_load_elf_segs(proc, data);
proc->platformdata.trapframe.ss = 0x20 | 0x3;
proc->platformdata.trapframe.rsp = (uint64_t)VIRT(sp);
proc->platformdata.trapframe.rflags = 0x202;
proc->platformdata.trapframe.cs = 0x18 | 0x3;
proc->platformdata.trapframe.rip = aux.entry;
#endif
proc->state = PROC_READY;
proc->pid = pids++;
return proc;
}
void proc_register(Proc *proc) {
spinlock_acquire(&PROCS.spinlock);
LL_APPEND(PROCS.procs, proc);
@ -63,24 +177,53 @@ Proc *proc_nextready(void) {
return proc;
}
void proc_reaper(void) {
Proc *head = PROCS.procs;
while (head) {
if (head->state == PROC_ZOMBIE) {
Proc *zombie = head;
head = head->next;
LL_REMOVE(PROCS.procs, zombie);
#if defined(__x86_64__)
pmm_free((uintptr_t)(zombie->platformdata.kstack - PROC_STACKSIZE), PROC_STACKBLOCKS);
#endif
if (!zombie->kern) {
VasRange *vashead = zombie->vas;
size_t i = 0;
while (vashead) {
VasRange *tmp = vashead;
vashead = vashead->next;
#if defined(__x86_64__)
hal_vmm_unmap_range(zombie->platformdata.cr3, tmp->virtstart, tmp->physstart, tmp->size);
#endif
// first pmm mapping is for the elf itself
if (i == 0) {
pmm_free((uintptr_t)tmp->physstart, tmp->size / HAL_PAGE_SIZE);
}
dlfree(tmp);
i++;
}
#if defined(__x86_64__)
pmm_free((uintptr_t)zombie->platformdata.cr3, 1);
#endif
}
dlfree(zombie);
} else {
head = head->next;
}
}
}
void proc_sched(void *cpustate) {
hal_intr_disable();
sched_ticks++;
if (sched_ticks % PROC_REAPER_FREQ == 0) {
Proc *head = PROCS.procs;
while (head) {
if (head->state == PROC_ZOMBIE) {
Proc *zombie = head;
head = head->next;
LL_REMOVE(PROCS.procs, zombie);
pmm_free((uintptr_t)(zombie->platformdata.kstack - PROC_STACKSIZE), PROC_STACKBLOCKS);
dlfree(zombie);
} else {
head = head->next;
}
}
proc_reaper();
}
#if defined(__x86_64__)
@ -116,31 +259,18 @@ void proc_idle(void) {
}
}
int a = 0;
void proc_print(void) {
void proc_status(void) {
for (;;) {
hal_wait(1 * 1000);
/* if (a == 10) { */
/* PROC_DIE(); */
/* } */
kprintf("A");
a++;
}
}
int b = 0;
void proc_print2(void) {
for (;;) {
hal_wait(2 * 1000);
/* if (b == 20) { */
/* PROC_DIE(); */
/* } */
kprintf("B");
b++;
spinlock_acquire(&PROCS.spinlock);
Proc *head = PROCS.procs;
while (head) {
kprintf("%s %s\n", head->kern ? "kern" : "user", head->name);
head = head->next;
}
kprintf("\n\n");
spinlock_release(&PROCS.spinlock);
hal_wait(3 * 1000);
}
}
@ -152,8 +282,8 @@ void proc_init(void) {
proc_register(idle);
PROCS.current = idle;
proc_register(proc_spawnkern(&proc_print, "print"));
proc_register(proc_spawnkern(&proc_print2, "print"));
proc_register(proc_spawnkern(&proc_status, "status"));
proc_register(proc_spawnuser("base", "/bin/hello"));
#if defined(__x86_64__)
hal_switchproc(&PROCS.current->platformdata.trapframe, (void *)PROCS.current->platformdata.cr3);