This commit is contained in:
2025-09-15 22:35:15 +02:00
parent ce63020b34
commit 0a5523f234
22 changed files with 374 additions and 177 deletions

View File

@ -1 +1,2 @@
print "this is an init script!" @print "this is an init script!"
base:/bin/pctl ls

View File

@ -9,11 +9,11 @@
#include "kprintf.h" #include "kprintf.h"
#include "spinlock/spinlock.h" #include "spinlock/spinlock.h"
PgTable *KERNEL_CR3 = NULL; uint64_t KERNEL_CR3 = 0;
SpinLock spinlock; SpinLock spinlock;
PgTable *hal_vmm_current_cr3(void) { uint64_t hal_vmm_current_cr3(void) {
PgTable *cr3; uint64_t cr3;
asm volatile("mov %%cr3, %0" : "=r"(cr3)); asm volatile("mov %%cr3, %0" : "=r"(cr3));
return cr3; return cr3;
} }
@ -30,92 +30,93 @@ PgIndex hal_vmm_pageindex(uint64_t vaddr) {
} }
uint64_t *hal_vmm_nexttable(uint64_t *table, uint64_t ent) { uint64_t *hal_vmm_nexttable(uint64_t *table, uint64_t ent) {
uint8_t *addr; uint64_t entry = table[ent];
uint64_t phys;
if (table[ent] & HAL_PG_PRESENT) { if (entry & HAL_PG_PRESENT) {
addr = (uint8_t *)(table[ent] & ~((uint64_t)0xfff)); phys = entry & ~0xFFFULL;
} else { } else {
addr = pmm_alloc(1); uint8_t *newphys = pmm_alloc(1);
hal_memset(BOOT_INFO.hhdm_off + addr, 0, HAL_PAGE_SIZE); phys = (uint64_t)newphys;
table[ent] = (uint64_t)addr | HAL_PG_USER | HAL_PG_RW | HAL_PG_PRESENT; hal_memset(VIRT(phys), 0, HAL_PAGE_SIZE);
table[ent] = phys | HAL_PG_USER | HAL_PG_RW | HAL_PG_PRESENT;
}
return (uint64_t *)((uint8_t *)VIRT(phys));
} }
return (uint64_t *)(BOOT_INFO.hhdm_off + addr); void hal_vmm_map_page(uint64_t cr3phys, uint64_t virtaddr, uint64_t physaddr, uint32_t flags) {
} uint64_t *pml4 = (uint64_t *)VIRT(cr3phys);
void hal_vmm_map_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr, uint32_t flags) {
PgIndex pi = hal_vmm_pageindex(virtaddr); PgIndex pi = hal_vmm_pageindex(virtaddr);
uint64_t *pml3 = hal_vmm_nexttable((uint64_t *)pml4, pi.pml4); uint64_t *pml3 = hal_vmm_nexttable(pml4, pi.pml4);
uint64_t *pml2 = hal_vmm_nexttable((uint64_t *)pml3, pi.pml3); uint64_t *pml2 = hal_vmm_nexttable(pml3, pi.pml3);
uint64_t *pml1 = hal_vmm_nexttable((uint64_t *)pml2, pi.pml2); uint64_t *pml1 = hal_vmm_nexttable(pml2, pi.pml2);
uint64_t *pte = &pml1[pi.pml1]; uint64_t *pte = &pml1[pi.pml1];
*pte = (physaddr & ~0xFFF) | (flags & 0x7); *pte = (physaddr & ~0xFFFULL) | ((uint64_t)flags & 0x7ULL);
} }
void hal_vmm_unmap_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr) { void hal_vmm_unmap_page(uint64_t cr3phys, uint64_t virtaddr, uint64_t physaddr) {
uint64_t *pml4 = (uint64_t *)VIRT(cr3phys);
PgIndex pi = hal_vmm_pageindex(virtaddr); PgIndex pi = hal_vmm_pageindex(virtaddr);
uint64_t *pml3 = hal_vmm_nexttable((uint64_t *)pml4, pi.pml4); uint64_t *pml3 = hal_vmm_nexttable(pml4, pi.pml4);
uint64_t *pml2 = hal_vmm_nexttable((uint64_t *)pml3, pi.pml3); uint64_t *pml2 = hal_vmm_nexttable(pml3, pi.pml3);
uint64_t *pml1 = hal_vmm_nexttable((uint64_t *)pml2, pi.pml2); uint64_t *pml1 = hal_vmm_nexttable(pml2, pi.pml2);
uint64_t *pte = &pml1[pi.pml1]; uint64_t *pte = &pml1[pi.pml1];
*pte &= ~HAL_PG_PRESENT; *pte &= ~HAL_PG_PRESENT;
} }
void hal_vmm_map_range(PgTable *cr3, void *virtstart, void *physstart, size_t size, uint32_t flags) { void hal_vmm_map_range(uint64_t cr3phys, void *virtstart, void *physstart, size_t size, uint32_t flags) {
if (size % HAL_PAGE_SIZE != 0 || (uint64_t)virtstart % HAL_PAGE_SIZE != 0 || (uint64_t)physstart % HAL_PG_PRESENT != 0) { if (size % HAL_PAGE_SIZE != 0 || (uint64_t)virtstart % HAL_PAGE_SIZE != 0 || (uint64_t)physstart % HAL_PAGE_SIZE != 0) {
return; return;
} }
spinlock_acquire(&spinlock); spinlock_acquire(&spinlock);
uint8_t *vaddr = virtstart, *paddr = physstart; uint8_t *vaddr = (uint8_t *)virtstart;
uint8_t *paddr = (uint8_t *)physstart;
for (; vaddr <= ((uint8_t *)virtstart + size); vaddr += HAL_PAGE_SIZE, paddr += HAL_PAGE_SIZE) { uint8_t *end = (uint8_t *)virtstart + size;
hal_vmm_map_page(cr3, (uint64_t)vaddr, (uint64_t)paddr, flags); for (; vaddr < end; vaddr += HAL_PAGE_SIZE, paddr += HAL_PAGE_SIZE) {
hal_vmm_map_page(cr3phys, (uint64_t)vaddr, (uint64_t)paddr, flags);
} }
spinlock_release(&spinlock); spinlock_release(&spinlock);
} }
void hal_vmm_unmap_range(PgTable *cr3, void *virtstart, void *physstart, size_t size) { void hal_vmm_unmap_range(uint64_t cr3phys, void *virtstart, void *physstart, size_t size) {
if (size % HAL_PAGE_SIZE != 0 || (uint64_t)virtstart % HAL_PAGE_SIZE != 0 || (uint64_t)physstart % HAL_PG_PRESENT != 0) { if (size % HAL_PAGE_SIZE != 0 || (uint64_t)virtstart % HAL_PAGE_SIZE != 0 || (uint64_t)physstart % HAL_PAGE_SIZE != 0) {
return; return;
} }
spinlock_acquire(&spinlock); spinlock_acquire(&spinlock);
uint8_t *vaddr = virtstart, *paddr = physstart; uint8_t *vaddr = (uint8_t *)virtstart;
uint8_t *paddr = (uint8_t *)physstart;
uint8_t *end = vaddr + size;
for (; vaddr <= ((uint8_t *)virtstart + size); vaddr += HAL_PAGE_SIZE, paddr += HAL_PAGE_SIZE) { for (; vaddr < end; vaddr += HAL_PAGE_SIZE, paddr += HAL_PAGE_SIZE) {
hal_vmm_unmap_page(cr3, (uint64_t)vaddr, (uint64_t)paddr); hal_vmm_unmap_page(cr3phys, (uint64_t)vaddr, (uint64_t)paddr);
} }
spinlock_release(&spinlock); spinlock_release(&spinlock);
} }
void hal_vmm_map_kern(PgTable *cr3) { void hal_vmm_map_kern(uint64_t targetcr3) {
PgTable *kcr3 = BOOT_INFO.hhdm_off + KERNEL_CR3; uint64_t *kcr3 = (uint64_t *)VIRT(KERNEL_CR3);
uint64_t *cr3 = (uint64_t *)VIRT(targetcr3);
for (size_t i = 256; i < 512; i++) { for (size_t i = 256; i < 512; i++) {
cr3->ents[i] = kcr3->ents[i]; cr3[i] = kcr3[i];
} }
} }
void hal_vmm_switch_pd(PgTable *cr3) { uint64_t hal_vmm_userproc_pml4_phys(Proc *proc) {
hal_loadpd(cr3); uint8_t *cr3phys = pmm_alloc(1);
} uint64_t phys = (uint64_t)cr3phys;
hal_memset(VIRT(phys), 0, HAL_PAGE_SIZE);
PgTable *hal_vmm_userproc_pml4(Proc *proc) {
uint8_t *cr3 = pmm_alloc(1);
PgTable *pml4 = (PgTable *)VIRT(cr3);
hal_memset(pml4, 0, HAL_PAGE_SIZE);
PgTable *kcr3 = VIRT(KERNEL_CR3);
uint64_t *kcr3 = (uint64_t *)VIRT(KERNEL_CR3);
uint64_t *pml4 = (uint64_t *)VIRT(phys);
for (size_t i = 256; i < 512; i++) { for (size_t i = 256; i < 512; i++) {
pml4->ents[i] = kcr3->ents[i]; pml4[i] = kcr3[i];
} }
return phys;
return (PgTable *)cr3;
} }
void hal_vmm_init(void) { void hal_vmm_init(void) {

View File

@ -26,10 +26,14 @@ enum {
}; };
typedef struct { typedef struct {
uint64_t pml4; uint16_t pml4;
uint64_t pml3; uint16_t pml3;
uint64_t pml2; uint16_t pml2;
uint64_t pml1; uint16_t pml1;
/* uint64_t pml4; */
/* uint64_t pml3; */
/* uint64_t pml2; */
/* uint64_t pml1; */
} PACKED PgIndex; } PACKED PgIndex;
typedef struct { typedef struct {
@ -39,25 +43,32 @@ typedef struct {
bool writethrough: 1; bool writethrough: 1;
bool cachedisabled: 1; bool cachedisabled: 1;
bool accessed: 1; bool accessed: 1;
bool zero0: 1; bool dirty: 1;
bool size: 1; bool hugepage: 1;
bool zero1: 1; bool global: 1;
uint8_t avail: 3; uint8_t avail: 3;
uint64_t addr: 52; uint64_t addr: 40;
uint16_t osdef: 11;
bool nx: 1;
/* bool zero0: 1; */
/* bool size: 1; */
/* bool zero1: 1; */
/* uint8_t avail: 3; */
/* uint64_t addr: 52; */
} PACKED Pte; } PACKED Pte;
typedef struct { typedef struct {
Pte ents[512]; Pte ents[512];
} PACKED PgTable; } PACKED PgTable;
extern PgTable *KERNEL_CR3; extern uint64_t KERNEL_CR3;
void hal_vmm_init(void); void hal_vmm_init(void);
void hal_vmm_unmap_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr); void hal_vmm_unmap_page(uint64_t cr3phys, uint64_t virtaddr, uint64_t physaddr);
void hal_vmm_map_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr, uint32_t flags); void hal_vmm_map_page(uint64_t cr3phys, uint64_t virtaddr, uint64_t physaddr, uint32_t flags);
PgTable *hal_vmm_current_cr3(void); uint64_t hal_vmm_current_cr3(void);
void hal_vmm_map_range(PgTable *cr3, void *virtstart, void *physstart, size_t size, uint32_t flags); void hal_vmm_map_range(uint64_t cr3phys, void *virtstart, void *physstart, size_t size, uint32_t flags);
void hal_vmm_unmap_range(PgTable *cr3, void *virtstart, void *physstart, size_t size); void hal_vmm_unmap_range(uint64_t cr3phys, void *virtstart, void *physstart, size_t size);
PgTable *hal_vmm_userproc_pml4(struct Proc *proc); uint64_t hal_vmm_userproc_pml4_phys(struct Proc *proc);
#endif // HAL_VMM_H_ #endif // HAL_VMM_H_

View File

@ -34,7 +34,6 @@ bool proc_checkelf(uint8_t *elf) {
} }
ElfAuxval proc_load_elf_segs(Proc *proc, uint8_t *data) { ElfAuxval proc_load_elf_segs(Proc *proc, uint8_t *data) {
PgTable *vas = proc->platformdata.cr3;
ElfAuxval aux = {0}; ElfAuxval aux = {0};
Elf64_Ehdr *elfhdr = (Elf64_Ehdr *)data; Elf64_Ehdr *elfhdr = (Elf64_Ehdr *)data;
@ -51,16 +50,16 @@ ElfAuxval proc_load_elf_segs(Proc *proc, uint8_t *data) {
} break; } break;
case PT_LOAD: { case PT_LOAD: {
uint64_t off = phdr->p_vaddr & (HAL_PAGE_SIZE - 1); uint64_t off = phdr->p_vaddr & (HAL_PAGE_SIZE - 1);
uint64_t blocks = (phdr->p_memsz / HAL_PAGE_SIZE) + 1; uint64_t blocks = (off + phdr->p_memsz + HAL_PAGE_SIZE - 1) / HAL_PAGE_SIZE;
uint8_t *physaddr = pmm_alloc(blocks); uint8_t *physaddr = pmm_alloc(blocks);
uint8_t *virtaddr = (uint8_t *)(phdr->p_vaddr - off); uint8_t *virtaddr = (uint8_t *)(phdr->p_vaddr & ~(HAL_PAGE_SIZE - 1));
hal_memset(VIRT(physaddr), 0, phdr->p_memsz); hal_memset(VIRT(physaddr), 0, blocks * HAL_PAGE_SIZE);
hal_memcpy(VIRT(physaddr) + off, (data + phdr->p_offset), phdr->p_filesz); hal_memcpy(VIRT(physaddr) + off, (data + phdr->p_offset), phdr->p_filesz);
uint32_t pgflags = HAL_PG_USER | HAL_PG_RW | HAL_PG_PRESENT; 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); hal_vmm_map_range(proc->platformdata.cr3, virtaddr, physaddr, blocks * HAL_PAGE_SIZE, pgflags);
VasRange *range = dlmalloc(sizeof(*range)); VasRange *range = dlmalloc(sizeof(*range));
range->virtstart = virtaddr; range->virtstart = virtaddr;
@ -89,15 +88,15 @@ Proc *proc_spawnkern(void (*ent)(void), char *name) {
proc->kern = true; proc->kern = true;
uint8_t *sp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS) + PROC_STACKSIZE; uint8_t *pstackp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS) + PROC_STACKSIZE;
uint8_t *kstackp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS) + PROC_STACKSIZE; uint8_t *kstackp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS) + PROC_STACKSIZE;
proc->platformdata.kstack = kstackp; proc->platformdata.kstack = kstackp;
proc->platformdata.pstack = sp; proc->platformdata.pstack = pstackp;
hal_memset(&proc->platformdata.trapframe, 0, sizeof(proc->platformdata.trapframe)); hal_memset(&proc->platformdata.trapframe, 0, sizeof(proc->platformdata.trapframe));
proc->platformdata.trapframe.ss = 0x10; proc->platformdata.trapframe.ss = 0x10;
proc->platformdata.trapframe.rsp = (uint64_t)VIRT(sp); proc->platformdata.trapframe.rsp = (uint64_t)VIRT(pstackp);
proc->platformdata.trapframe.rflags = 0x202; proc->platformdata.trapframe.rflags = 0x202;
proc->platformdata.trapframe.cs = 0x08; proc->platformdata.trapframe.cs = 0x08;
proc->platformdata.trapframe.rip = (uint64_t)ent; proc->platformdata.trapframe.rip = (uint64_t)ent;
@ -145,30 +144,49 @@ Proc *proc_spawnuser(char *mountpoint, char *path) {
hal_memset(proc, 0, sizeof(*proc)); hal_memset(proc, 0, sizeof(*proc));
ksprintf(proc->name, "%s:%s", mountpoint, path); ksprintf(proc->name, "%s:%s", mountpoint, path);
uint8_t *sp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS) + PROC_STACKSIZE; hal_memset(&proc->platformdata.trapframe, 0, sizeof(proc->platformdata.trapframe));
uint8_t *spbase = sp - PROC_STACKSIZE; proc->platformdata.cr3 = hal_vmm_userproc_pml4_phys(proc);
uint8_t *kstackp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS) + PROC_STACKSIZE; uint8_t *kstackp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS) + PROC_STACKSIZE;
proc->platformdata.kstack = kstackp; proc->platformdata.kstack = kstackp;
proc->platformdata.pstack = sp; uint8_t *pstackp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS);
proc->platformdata.pstack = pstackp;
hal_memset(&proc->platformdata.trapframe, 0, sizeof(proc->platformdata.trapframe)); uint64_t virttop = PROC_USER_STACK_TOP;
uint64_t virtbase = virttop - PROC_STACKSIZE;
proc->platformdata.cr3 = hal_vmm_userproc_pml4(proc); uint32_t flags = HAL_PG_RW | HAL_PG_PRESENT | HAL_PG_USER;
hal_vmm_map_range(proc->platformdata.cr3, (void *)virtbase, (void *)pstackp, PROC_STACKSIZE, flags);
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)); VasRange *range = dlmalloc(sizeof(*range));
range->virtstart = spbase; range->virtstart = (uint8_t *)virtbase;
range->physstart = spbase; range->physstart = (uint8_t *)pstackp;
range->size = PROC_STACKSIZE; range->size = PROC_STACKSIZE;
range->pgflags = flags; range->pgflags = flags;
LL_APPEND(proc->vas, range); LL_APPEND(proc->vas, range);
/* uint8_t *sp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS) + PROC_STACKSIZE; */
/* uint8_t *spbase = sp - PROC_STACKSIZE; */
/* uint8_t *kstackp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS) + PROC_STACKSIZE; */
/* proc->platformdata.kstack = kstackp; */
/* proc->platformdata.pstack = sp; */
/* uint32_t flags = HAL_PG_RW | HAL_PG_USER | HAL_PG_PRESENT; */
/* hal_vmm_map_range(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); ElfAuxval aux = proc_load_elf_segs(proc, data);
proc->platformdata.trapframe.ss = 0x20 | 0x3; proc->platformdata.trapframe.ss = 0x20 | 0x3;
proc->platformdata.trapframe.rsp = (uint64_t)sp; proc->platformdata.trapframe.rsp = (uint64_t)virttop;
proc->platformdata.trapframe.rflags = 0x202; proc->platformdata.trapframe.rflags = 0x202;
proc->platformdata.trapframe.cs = 0x18 | 0x3; proc->platformdata.trapframe.cs = 0x18 | 0x3;
proc->platformdata.trapframe.rip = aux.entry; proc->platformdata.trapframe.rip = aux.entry;
@ -206,6 +224,7 @@ Proc *proc_nextready(void) {
} }
void proc_reaper(void) { void proc_reaper(void) {
spinlock_acquire(&PROCS.spinlock);
Proc *head = PROCS.procs; Proc *head = PROCS.procs;
while (head) { while (head) {
if (head->state == PROC_ZOMBIE) { if (head->state == PROC_ZOMBIE) {
@ -221,13 +240,13 @@ void proc_reaper(void) {
} }
} }
/* for (size_t i = 0; i < PROC_PIPEHANDLES_MAX; i++) { */ for (size_t i = 0; i < PROC_PIPEHANDLES_MAX; i++) {
/* if (zombie->pipes[i] != NULL && zombie->pipes[i]->ownerpid == zombie->pid) { */ if (zombie->pipes[i] != NULL && zombie->pipes[i]->ownerpid == zombie->pid) {
/* dlfree(zombie->pipes[i]); */ dlfree(zombie->pipes[i]);
/* ipc_pipefree(zombie->pipes[i]); */ ipc_pipefree(zombie->pipes[i]);
/* zombie->pipes[i] = NULL; */ zombie->pipes[i] = NULL;
/* } */ }
/* } */ }
pmm_free((uintptr_t)(zombie->platformdata.kstack - PROC_STACKSIZE), PROC_STACKBLOCKS); pmm_free((uintptr_t)(zombie->platformdata.kstack - PROC_STACKSIZE), PROC_STACKBLOCKS);
pmm_free((uintptr_t)(zombie->platformdata.pstack - PROC_STACKSIZE), PROC_STACKBLOCKS); pmm_free((uintptr_t)(zombie->platformdata.pstack - PROC_STACKSIZE), PROC_STACKBLOCKS);
@ -238,11 +257,8 @@ void proc_reaper(void) {
while (vashead) { while (vashead) {
VasRange *tmp = vashead; VasRange *tmp = vashead;
vashead = vashead->next; vashead = vashead->next;
hal_vmm_unmap_range(VIRT(zombie->platformdata.cr3), tmp->virtstart, tmp->physstart, tmp->size); hal_vmm_unmap_range(zombie->platformdata.cr3, tmp->virtstart, tmp->physstart, tmp->size);
// first pmm mapping is for the elf itself
if (i == 0) {
pmm_free((uintptr_t)tmp->physstart, tmp->size / HAL_PAGE_SIZE); pmm_free((uintptr_t)tmp->physstart, tmp->size / HAL_PAGE_SIZE);
}
dlfree(tmp); dlfree(tmp);
i++; i++;
} }
@ -262,6 +278,7 @@ void proc_reaper(void) {
head = head->next; head = head->next;
} }
} }
spinlock_release(&PROCS.spinlock);
} }
void proc_sched(void *cpustate) { void proc_sched(void *cpustate) {

View File

@ -11,7 +11,7 @@
#define PROC_NAME_MAX 0x100 #define PROC_NAME_MAX 0x100
#define PROC_STACKBLOCKS 32 #define PROC_STACKBLOCKS 256
#define PROC_STACKSIZE (PROC_STACKBLOCKS * BITMAP_BLOCK_SIZE) #define PROC_STACKSIZE (PROC_STACKBLOCKS * BITMAP_BLOCK_SIZE)
#define PROC_MAX 0x100 // max amount of processes #define PROC_MAX 0x100 // max amount of processes
@ -19,13 +19,14 @@
#define PROC_VFSHANDLES_MAX 0x80 #define PROC_VFSHANDLES_MAX 0x80
#define PROC_PIPEHANDLES_MAX 0x20 #define PROC_PIPEHANDLES_MAX 0x20
#define PROC_MMAN_MAP_BASE 0xC000000000 #define PROC_MMAN_MAP_BASE 0x0000004000000000ULL
#define PROC_USER_STACK_TOP 0x00007ffffffff000ULL
typedef struct { typedef struct {
IntrStackFrame trapframe; IntrStackFrame trapframe;
uint8_t *kstack; uint8_t *kstack;
uint8_t *pstack; uint8_t *pstack;
PgTable *cr3; uint64_t cr3;
} ProcPlatformData; } ProcPlatformData;
enum { enum {
@ -33,6 +34,7 @@ enum {
PROC_READY = 1, PROC_READY = 1,
PROC_ZOMBIE = 2, PROC_ZOMBIE = 2,
PROC_WAITING = 3, PROC_WAITING = 3,
PROC_DIED = 4,
}; };
typedef struct ProcArg { typedef struct ProcArg {

View File

@ -18,7 +18,7 @@ int32_t SYSCALL5(sys_mman_map, addr1, size1, prot1, flags1, out1) {
uint64_t flags = flags1; uint64_t flags = flags1;
uint8_t **out = (uint8_t **)out1; uint8_t **out = (uint8_t **)out1;
if (size % HAL_PAGE_SIZE != 0) { if (size == 0 || (size % HAL_PAGE_SIZE != 0)) {
if (out != NULL) { if (out != NULL) {
*out = NULL; *out = NULL;
} }
@ -37,11 +37,19 @@ int32_t SYSCALL5(sys_mman_map, addr1, size1, prot1, flags1, out1) {
spinlock_release(&PROCS.spinlock); spinlock_release(&PROCS.spinlock);
uint8_t *virt = NULL; uint8_t *virt = NULL;
if (flags & MMAN_MAP_F_FIXED && addr != NULL) { if ((flags & MMAN_MAP_F_FIXED) && addr != NULL) {
if ((uintptr_t)addr % HAL_PAGE_SIZE != 0) {
if (out != NULL) {
*out = NULL;
}
pmm_free((uintptr_t)phys, pages);
return E_INVALIDARGUMENT;
}
virt = addr; virt = addr;
} else { } else {
virt = (uint8_t *)proc->mman_map_base; virt = (uint8_t *)proc->mman_map_base;
proc->mman_map_base += size; proc->mman_map_base += pages * HAL_PAGE_SIZE;
} }
uint64_t pflags = HAL_PG_USER | HAL_PG_PRESENT; uint64_t pflags = HAL_PG_USER | HAL_PG_PRESENT;
@ -49,11 +57,11 @@ int32_t SYSCALL5(sys_mman_map, addr1, size1, prot1, flags1, out1) {
pflags |= HAL_PG_RW; pflags |= HAL_PG_RW;
} }
hal_vmm_map_range(VIRT(proc->platformdata.cr3), virt, phys, size, pflags); hal_vmm_map_range(proc->platformdata.cr3, virt, phys, pages * HAL_PAGE_SIZE, pflags);
VasRange *range = dlmalloc(sizeof(*range)); VasRange *range = dlmalloc(sizeof(*range));
range->virtstart = virt; range->virtstart = virt;
range->physstart = phys; range->physstart = phys;
range->size = size * HAL_PAGE_SIZE; range->size = pages * HAL_PAGE_SIZE;
range->pgflags = pflags; range->pgflags = pflags;
LL_APPEND(proc->vas, range); LL_APPEND(proc->vas, range);
@ -91,7 +99,7 @@ int32_t SYSCALL1(sys_mman_unmap, addr1) {
return E_INVALIDARGUMENT; return E_INVALIDARGUMENT;
} }
hal_vmm_unmap_range(VIRT(proc->platformdata.cr3), tofree->virtstart, tofree->physstart, tofree->size); hal_vmm_unmap_range(proc->platformdata.cr3, tofree->virtstart, tofree->physstart, tofree->size);
LL_REMOVE(proc->vas, tofree); LL_REMOVE(proc->vas, tofree);
pmm_free((uintptr_t)tofree->physstart, tofree->size / HAL_PAGE_SIZE); pmm_free((uintptr_t)tofree->physstart, tofree->size / HAL_PAGE_SIZE);
dlfree(tofree); dlfree(tofree);

View File

@ -29,7 +29,7 @@ int32_t SYSCALL5(sys_processctl, pid1, cmd1, arg1, arg2, arg3) {
if (proc == NULL) { if (proc == NULL) {
if (cmd == PCTL_POLLSTATE) { if (cmd == PCTL_POLLSTATE) {
ret = 2; ret = PROC_DIED;
goto done; goto done;
} }
ret = E_INVALIDARGUMENT; ret = E_INVALIDARGUMENT;
@ -104,6 +104,44 @@ int32_t SYSCALL5(sys_processctl, pid1, cmd1, arg1, arg2, arg3) {
} }
ret = E_OK; ret = E_OK;
} break; } break;
case PCTL_PLS_SZ: {
size_t i = 0;
spinlock_acquire(&PROCS.spinlock);
Proc *p = PROCS.procs;
while (p) {
i++;
p = p->next;
}
spinlock_release(&PROCS.spinlock);
ret = i;
} break;
case PCTL_PLS_STAT: {
uint64_t pidx = arg1;
ProcStat *stat = (ProcStat *)arg2;
if (stat == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
size_t i = 0;
spinlock_acquire(&PROCS.spinlock);
Proc *p = PROCS.procs;
while (p) {
if (i == pidx) {
stat->pid = p->pid;
hal_strcpy(stat->name, p->name);
stat->state = p->state;
stat->kern = p->kern;
break;
}
i++;
p = p->next;
}
spinlock_release(&PROCS.spinlock);
ret = E_OK;
} break;
default: { default: {
ret = E_INVALIDARGUMENT; ret = E_INVALIDARGUMENT;
} break; } break;

View File

@ -1,5 +1,4 @@
CFLAGS += -m64 \ CFLAGS += -m64 \
-fPIE \
-mno-80387 \ -mno-80387 \
-mno-mmx \ -mno-mmx \
-mno-sse \ -mno-sse \

View File

@ -11,6 +11,16 @@ enum {
PCTL_GETPID = 4, PCTL_GETPID = 4,
PCTL_ARGLEN = 5, PCTL_ARGLEN = 5,
PCTL_ARGV = 6, PCTL_ARGV = 6,
PCTL_PLS_SZ = 7,
PCTL_PLS_STAT = 8,
}; };
typedef struct {
uint64_t pid;
char name[0x100];
uint8_t state;
size_t usemem;
bool kern;
} ProcStat;
#endif // SHARE_HDRS_PROCESSCTL_H_ #endif // SHARE_HDRS_PROCESSCTL_H_

View File

@ -8,11 +8,10 @@
#include <log.h> #include <log.h>
extern void main(void); extern void main(void);
void clearbss(void) {
extern uint8_t _bss_start; extern uint8_t _bss_start;
extern uint8_t _bss_end; extern uint8_t _bss_end;
void clearbss(void) {
uint8_t *ps = &_bss_start; uint8_t *ps = &_bss_start;
uint8_t *pe = &_bss_end; uint8_t *pe = &_bss_end;
size_t sz = pe - ps; size_t sz = pe - ps;

View File

@ -46,7 +46,7 @@ int RELEASE_LOCK(SpinLock *sl) {
} }
int INITIAL_LOCK(SpinLock *sl) { int INITIAL_LOCK(SpinLock *sl) {
spinlock_release(sl); spinlock_init(sl);
return 0; return 0;
} }
@ -79,12 +79,17 @@ void *sbrk(ptrdiff_t inc) {
return heap_end; return heap_end;
} }
uint8_t *oldh = heap_end; uint8_t *oldbrk = heap_end;
uint8_t *newh = heap_end + inc; uint8_t *newbrk = heap_end + inc;
if (newbrk < heap_start) {
return (void *)-1;
}
if (inc > 0) { if (inc > 0) {
if (newh > heap_commit) { if (newbrk > heap_commit) {
size_t extra = _roundpage((size_t)(newh - heap_commit)); size_t need = (size_t)(newbrk - heap_commit);
size_t extra = _roundpage(need);
uint8_t *maddr = NULL; uint8_t *maddr = NULL;
int32_t ret = mman_map(NULL, extra, MMAN_MAP_PF_RW, 0, &maddr); int32_t ret = mman_map(NULL, extra, MMAN_MAP_PF_RW, 0, &maddr);
if (ret != E_OK || maddr == NULL) { if (ret != E_OK || maddr == NULL) {
@ -92,39 +97,7 @@ void *sbrk(ptrdiff_t inc) {
} }
heap_commit += extra; heap_commit += extra;
} }
heap_end = newh;
} else {
heap_end = newh;
} }
return oldh; heap_end = newbrk;
return (void *)oldbrk;
#if 0
if (!heap_end) {
heap_end = heap_start;
}
if (inc == 0) {
return heap_end;
}
uint8_t *oldh = heap_end;
uint8_t *newh = heap_end + inc;
if (inc > 0) {
size_t allocsz = _roundpage((size_t)(newh - oldh));
uint8_t *maddr = NULL;
int32_t ret = mman_map(NULL, allocsz, MMAN_MAP_PF_RW, 0, &maddr);
if (ret != E_OK || maddr == NULL) {
return (void *)-1;
}
if (!heap_start) {
heap_start = maddr;
}
oldh = heap_end ? heap_end : maddr;
heap_end = oldh + allocsz;
} else {
heap_end = newh;
}
return oldh;
#endif
} }

View File

@ -1,7 +1,7 @@
ENTRY(_start) ENTRY(_start)
SECTIONS { SECTIONS {
/* . = 0x0000000000000000; */ . = 0x400000;
.text ALIGN(4K): .text ALIGN(4K):
{ {

View File

@ -2,7 +2,6 @@ include $(ROOT)/mk/user/x86_64.mk
include $(ROOT)/mk/arch/toolchain-x86_64.mk include $(ROOT)/mk/arch/toolchain-x86_64.mk
LDFLAGS += -m elf_x86_64 \ LDFLAGS += -m elf_x86_64 \
-pie \
--no-dynamic-linker \ --no-dynamic-linker \
-z text \ -z text \
-z max-page-size=0x1000 -z max-page-size=0x1000

View File

@ -7,18 +7,37 @@
#include <ansiq/all.h> #include <ansiq/all.h>
#include <string/char.h> #include <string/char.h>
#include <util/util.h> #include <util/util.h>
#include <dlmalloc/malloc.h>
#define SUBPROC_PIPE_OUT 0x1f
uint64_t PID;
void main(void) { void main(void) {
PID = (uint64_t)processctl(-1, PCTL_GETPID, 0, 0, 0);
ipcpipe(PID, SUBPROC_PIPE_OUT, IPCPIPE_MAKE, NULL, 0);
char *tbargs[] = { "-m", "runfile", "-f", "base:/scripts/init.tb" }; char *tbargs[] = { "-m", "runfile", "-f", "base:/scripts/init.tb" };
int32_t tb = processctl(-1, PCTL_SPAWN, (uint64_t)"base:/bin/tb", (uint64_t)&tbargs, ARRLEN(tbargs)); int32_t tb = processctl(-1, PCTL_SPAWN, (uint64_t)"base:/bin/tb", (uint64_t)&tbargs, ARRLEN(tbargs));
uint64_t selfpid = (uint64_t)processctl(-1, PCTL_GETPID, 0, 0, 0); ipcpipe(tb, IPCPIPE_OUT, IPCPIPE_REPLACE, (uint8_t *)PID, SUBPROC_PIPE_OUT);
ipcpipe(tb, IPCPIPE_OUT, IPCPIPE_REPLACE, (uint8_t *)selfpid, IPCPIPE_OUT);
processctl(tb, PCTL_RUN, 0, 0, 0);
ipcpipe(IPCPIPE_SELFPID, 10, IPCPIPE_MAKE, NULL, 0); ipcpipe(IPCPIPE_SELFPID, 10, IPCPIPE_MAKE, NULL, 0);
ipcpipe(IPCPIPE_SELFPID, 10, IPCPIPE_ADD_BCAST, NULL, 1); ipcpipe(IPCPIPE_SELFPID, 10, IPCPIPE_ADD_BCAST, NULL, 1);
while(processctl(tb, PCTL_POLLSTATE, 0, 0, 0) != 2) { processctl(tb, PCTL_RUN, 0, 0, 0);
#define OUTBUF_MAX 1024
char *outbuf = dlmalloc(1024);
while(processctl(tb, PCTL_POLLSTATE, 0, 0, 0) != 4) {
string_memset(outbuf, 0, OUTBUF_MAX);
int32_t nrd = ipcpipe(PID, SUBPROC_PIPE_OUT, IPCPIPE_READ, (uint8_t *)outbuf, sizeof(outbuf));
if (nrd > 0) {
uprintf("%s", outbuf);
}
#if 0
int32_t kbchr; int32_t kbchr;
int32_t read = ipcpipe(IPCPIPE_SELFPID, 10, IPCPIPE_READ, (uint8_t *)&kbchr, sizeof(kbchr)); int32_t read = ipcpipe(IPCPIPE_SELFPID, 10, IPCPIPE_READ, (uint8_t *)&kbchr, sizeof(kbchr));
if (read > 0) { if (read > 0) {
@ -32,6 +51,9 @@ void main(void) {
} }
} }
} }
} #endif
}
for(;;);
} }

24
user/pctl/Makefile Normal file
View File

@ -0,0 +1,24 @@
include $(ROOT)/mk/grabsrc.mk
include ../Makefile.inc
.PHONY: all clean
TARGET := pctl
LDFLAGS += -L$(ROOT)/ulib -l:libulib.a
SRCFILES := $(call GRABSRC, .)
CFILES := $(call GET_CFILES, $(SRCFILES))
OBJ := $(call GET_OBJ, $(SRCFILES))
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
all: $(TARGET)
$(TARGET): $(OBJ)
$(LD) $^ $(LDFLAGS) -o $@
echo $$(realpath $(TARGET)) >> $(FILES)
clean:
rm -f $(OBJ) $(TARGET)

30
user/pctl/main.c Normal file
View File

@ -0,0 +1,30 @@
#include <stddef.h>
#include <stdint.h>
#include <system/system.h>
#include <sysdefs/processctl.h>
#include <uprintf.h>
#include <args/args.h>
#include <string/string.h>
#include <util/util.h>
#include <errors.h>
void main(void) {
if (argslen() == 0) {
return;
}
char *cmd = args()[0];
if (string_strcmp(cmd, "ls") == 0) {
uint64_t procslen = processctl(-1, PCTL_PLS_SZ, 0, 0, 0);
for (size_t i = 0; i < procslen; i++) {
ProcStat stat = ZERO(&stat);
int32_t r = processctl(-1, PCTL_PLS_STAT, i, (uint64_t)&stat, 0);
if (r == E_OK) {
uprintf("%-30s %lu %-6s\n", stat.name, stat.pid, stat.kern ? "KERNEL" : "USER");
}
}
} else {
uprintf("pctl: unknown command\n");
}
}

BIN
user/pctl/main.o Normal file

Binary file not shown.

BIN
user/pctl/pctl Executable file

Binary file not shown.

View File

@ -5,10 +5,17 @@
#include <string/char.h> #include <string/char.h>
#include <linklist.h> #include <linklist.h>
#include <dlmalloc/malloc.h> #include <dlmalloc/malloc.h>
#include <system/system.h>
#include <sysdefs/processctl.h>
#include <sysdefs/ipcpipe.h>
#include <uprintf.h> #include <uprintf.h>
#include "interp.h" #include "interp.h"
#include "runtime.h" #include "runtime.h"
#define SUBPROC_PIPE_OUT 0x1f
extern uint64_t PID;
static InterpResult RES; static InterpResult RES;
void tz_init(Tokenizer *tz, const char *str, size_t len) { void tz_init(Tokenizer *tz, const char *str, size_t len) {
@ -62,7 +69,7 @@ void tz_classify(Tokenizer *tz) {
while (tk) { while (tk) {
if (tk->ptr[0] == '"' && tk->ptr[tk->len - 1] == '"') { if (tk->ptr[0] == '"' && tk->ptr[tk->len - 1] == '"') {
tk->type = TOK_STRING; tk->type = TOK_STRING;
} else { } else if (tk->ptr[0] == '@') {
RtCmd *cmd = RTCMDS; RtCmd *cmd = RTCMDS;
while (cmd) { while (cmd) {
char tmpbuf[0xff] = {0}; char tmpbuf[0xff] = {0};
@ -74,6 +81,8 @@ void tz_classify(Tokenizer *tz) {
} }
cmd = cmd->next; cmd = cmd->next;
} }
} else {
tk->type = TOK_MISC;
} }
tk = tk->next; tk = tk->next;
} }
@ -132,8 +141,9 @@ bool interp_readline(char *data, const char **bgptr, const char **endptr) {
return true; return true;
} }
bool interp_runstring(const char *string, size_t len, InterpResult **res) { bool interp_runstring(const char *string, InterpResult **res) {
*res = &RES; *res = &RES;
string_memset(RES.errmsg, 0, sizeof(RES.errmsg));
rt_init(); rt_init();
bool ok = true; bool ok = true;
@ -156,13 +166,7 @@ bool interp_runstring(const char *string, size_t len, InterpResult **res) {
tz_classify(&tz); tz_classify(&tz);
Token *cmdtk = tz.tokens; Token *cmdtk = tz.tokens;
if (cmdtk->type != TOK_CMD) { if (cmdtk->type == TOK_CMD) {
ok = false;
usprintf(RES.errmsg, "Expected cmd name, but got %.*s", (int)cmdtk->len, cmdtk->ptr);
tz_free(&tz);
goto done;
}
ok = cmdtk->cmd->fn(cmdtk->next); ok = cmdtk->cmd->fn(cmdtk->next);
if (!ok) { if (!ok) {
ok = false; ok = false;
@ -170,6 +174,55 @@ bool interp_runstring(const char *string, size_t len, InterpResult **res) {
tz_free(&tz); tz_free(&tz);
goto done; goto done;
} }
} else if (cmdtk->type == TOK_MISC) {
char *appname = dlmalloc(1024);
usprintf(appname, "%.*s", (int)cmdtk->len, cmdtk->ptr);
size_t argslen1 = 0;
Token *argtk = cmdtk->next;
while (argtk) {
argslen1++;
argtk = argtk->next;
}
char **args1 = (char **)dlmalloc(sizeof(char *) * argslen1);
argtk = cmdtk->next;
size_t i = 0;
while (argtk) {
args1[i] = (char *)dlmalloc(PROC_ARG_MAX);
string_memset(args1[i], 0, PROC_ARG_MAX);
string_memcpy(args1[i], argtk->ptr, argtk->len);
i++;
argtk = argtk->next;
}
#define OUTBUF_MAX 1024
char *outbuf = dlmalloc(OUTBUF_MAX);
ipcpipe(PID, SUBPROC_PIPE_OUT, IPCPIPE_MAKE, NULL, 0);
int32_t app = processctl(-1, PCTL_SPAWN, (uint64_t)(char *)appname, (uint64_t)args1, argslen1);
ipcpipe(app, IPCPIPE_OUT, IPCPIPE_REPLACE, (uint8_t *)PID, SUBPROC_PIPE_OUT);
ipcpipe(app, IPCPIPE_IN, IPCPIPE_READ, (uint8_t *)PID, IPCPIPE_IN);
processctl(app, PCTL_RUN, 0, 0, 0);
while (processctl(app, PCTL_POLLSTATE, 0, 0, 0) != 4) {
string_memset(outbuf, 0, OUTBUF_MAX);
int32_t nrd = ipcpipe(PID, SUBPROC_PIPE_OUT, IPCPIPE_READ, (uint8_t *)outbuf, sizeof(outbuf));
if (nrd > 0) {
uprintf("%s", outbuf);
}
}
dlfree(outbuf);
for (size_t j = 0; j < argslen1; j++) {
dlfree(args1[j]);
}
dlfree(args1);
dlfree(appname);
}
tz_free(&tz); tz_free(&tz);
} }

View File

@ -19,6 +19,7 @@ typedef struct Token {
enum { enum {
TOK_STRING, TOK_STRING,
TOK_CMD, TOK_CMD,
TOK_MISC,
} type; } type;
struct RtCmd *cmd; struct RtCmd *cmd;
@ -32,6 +33,6 @@ typedef struct {
Token *tokens; Token *tokens;
} Tokenizer; } Tokenizer;
bool interp_runstring(const char *string, size_t len, InterpResult **res); bool interp_runstring(const char *string, InterpResult **res);
#endif // TB_INTERP_H_ #endif // TB_INTERP_H_

View File

@ -15,6 +15,8 @@
#include <util/util.h> #include <util/util.h>
#include "interp.h" #include "interp.h"
uint64_t PID;
struct { struct {
char *modestr; char *modestr;
enum { MODE_INTERACTIVE = 1, MODE_RUNFILE = 2 } mode; enum { MODE_INTERACTIVE = 1, MODE_RUNFILE = 2 } mode;
@ -68,7 +70,8 @@ void do_file(char *filepath) {
LOG(LOG_ERR, "%s is not a file (%d)\n", filepath, statbuf.type); LOG(LOG_ERR, "%s is not a file (%d)\n", filepath, statbuf.type);
return; return;
} }
uint8_t *buf = dlmalloc(statbuf.size); uint8_t *buf = dlmalloc(statbuf.size+1);
string_memset(buf, 0, statbuf.size+1);
if ((ret = ioctl(ioh, IOCTL_READ, (uint64_t)buf, statbuf.size, 0)) < 0) { if ((ret = ioctl(ioh, IOCTL_READ, (uint64_t)buf, statbuf.size, 0)) < 0) {
LOG(LOG_ERR, "Could not read %s (%d): %s\n", filepath, ioh, ERRSTRING(ioh)); LOG(LOG_ERR, "Could not read %s (%d): %s\n", filepath, ioh, ERRSTRING(ioh));
@ -76,7 +79,7 @@ void do_file(char *filepath) {
} }
InterpResult *res; InterpResult *res;
bool ok = interp_runstring((const char *)buf, statbuf.size, &res); bool ok = interp_runstring((const char *)buf, &res);
if (!ok) { if (!ok) {
uprintf("Interpreter error:\n"); uprintf("Interpreter error:\n");
uprintf("%s\n", res->errmsg); uprintf("%s\n", res->errmsg);
@ -105,10 +108,16 @@ void do_mode_interactive(void) {
} }
linebuf[cursor - 1] = '\0'; linebuf[cursor - 1] = '\0';
uprintf("\n"); uprintf("\n");
InterpResult *res;
if (!interp_runstring(linebuf, &res)) {
LOG(LOG_ERR, "%s\n", res->errmsg);
}
} }
} }
void main(void) { void main(void) {
PID = processctl(-1, PCTL_GETPID, 0, 0, 0);
set_config(); set_config();
if (CONFIG.mode == MODE_INTERACTIVE) { if (CONFIG.mode == MODE_INTERACTIVE) {

View File

@ -8,11 +8,11 @@
RtCmd *RTCMDS = NULL; RtCmd *RTCMDS = NULL;
#define RTCMD(name) \ #define RTCMD(name, _fn) \
do { \ do { \
RtCmd *_cmd = dlmalloc(sizeof(*_cmd)); \ RtCmd *_cmd = dlmalloc(sizeof(*_cmd)); \
_cmd->cmdname = #name; \ _cmd->cmdname = (name); \
_cmd->fn = rt_##name; \ _cmd->fn = (_fn); \
LL_APPEND(RTCMDS, _cmd); \ LL_APPEND(RTCMDS, _cmd); \
} while(0) } while(0)
@ -25,10 +25,10 @@ bool rt_print(Token *tks) {
} }
tk = tk->next; tk = tk->next;
} }
uprintf("\n");
return true; return true;
} }
void rt_init(void) { void rt_init(void) {
RTCMD(print); RTCMD("@print", &rt_print);
} }