diff --git a/base/scripts/init.tb b/base/scripts/init.tb index 1528747..0ff3e62 100644 --- a/base/scripts/init.tb +++ b/base/scripts/init.tb @@ -1 +1,2 @@ -print "this is an init script!" +@print "this is an init script!" +base:/bin/pctl ls diff --git a/kernel/hal/x86_64/vmm.c b/kernel/hal/x86_64/vmm.c index 9886977..05656b8 100644 --- a/kernel/hal/x86_64/vmm.c +++ b/kernel/hal/x86_64/vmm.c @@ -9,11 +9,11 @@ #include "kprintf.h" #include "spinlock/spinlock.h" -PgTable *KERNEL_CR3 = NULL; +uint64_t KERNEL_CR3 = 0; SpinLock spinlock; -PgTable *hal_vmm_current_cr3(void) { - PgTable *cr3; +uint64_t hal_vmm_current_cr3(void) { + uint64_t cr3; asm volatile("mov %%cr3, %0" : "=r"(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) { - uint8_t *addr; - - if (table[ent] & HAL_PG_PRESENT) { - addr = (uint8_t *)(table[ent] & ~((uint64_t)0xfff)); + uint64_t entry = table[ent]; + uint64_t phys; + if (entry & HAL_PG_PRESENT) { + phys = entry & ~0xFFFULL; } else { - addr = pmm_alloc(1); - hal_memset(BOOT_INFO.hhdm_off + addr, 0, HAL_PAGE_SIZE); - table[ent] = (uint64_t)addr | HAL_PG_USER | HAL_PG_RW | HAL_PG_PRESENT; + uint8_t *newphys = pmm_alloc(1); + phys = (uint64_t)newphys; + hal_memset(VIRT(phys), 0, HAL_PAGE_SIZE); + table[ent] = phys | HAL_PG_USER | HAL_PG_RW | HAL_PG_PRESENT; } - - return (uint64_t *)(BOOT_INFO.hhdm_off + addr); + return (uint64_t *)((uint8_t *)VIRT(phys)); } -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) { + uint64_t *pml4 = (uint64_t *)VIRT(cr3phys); PgIndex pi = hal_vmm_pageindex(virtaddr); - uint64_t *pml3 = hal_vmm_nexttable((uint64_t *)pml4, pi.pml4); - uint64_t *pml2 = hal_vmm_nexttable((uint64_t *)pml3, pi.pml3); - uint64_t *pml1 = hal_vmm_nexttable((uint64_t *)pml2, pi.pml2); + uint64_t *pml3 = hal_vmm_nexttable(pml4, pi.pml4); + uint64_t *pml2 = hal_vmm_nexttable(pml3, pi.pml3); + uint64_t *pml1 = hal_vmm_nexttable(pml2, pi.pml2); 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); - - uint64_t *pml3 = hal_vmm_nexttable((uint64_t *)pml4, pi.pml4); - uint64_t *pml2 = hal_vmm_nexttable((uint64_t *)pml3, pi.pml3); - uint64_t *pml1 = hal_vmm_nexttable((uint64_t *)pml2, pi.pml2); + + uint64_t *pml3 = hal_vmm_nexttable(pml4, pi.pml4); + uint64_t *pml2 = hal_vmm_nexttable(pml3, pi.pml3); + uint64_t *pml1 = hal_vmm_nexttable(pml2, pi.pml2); uint64_t *pte = &pml1[pi.pml1]; *pte &= ~HAL_PG_PRESENT; } -void hal_vmm_map_range(PgTable *cr3, 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) { +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_PAGE_SIZE != 0) { return; } spinlock_acquire(&spinlock); - uint8_t *vaddr = virtstart, *paddr = physstart; - - for (; vaddr <= ((uint8_t *)virtstart + size); vaddr += HAL_PAGE_SIZE, paddr += HAL_PAGE_SIZE) { - hal_vmm_map_page(cr3, (uint64_t)vaddr, (uint64_t)paddr, flags); + uint8_t *vaddr = (uint8_t *)virtstart; + uint8_t *paddr = (uint8_t *)physstart; + uint8_t *end = (uint8_t *)virtstart + size; + 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); } -void hal_vmm_unmap_range(PgTable *cr3, 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) { +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_PAGE_SIZE != 0) { return; } 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) { - hal_vmm_unmap_page(cr3, (uint64_t)vaddr, (uint64_t)paddr); + for (; vaddr < end; vaddr += HAL_PAGE_SIZE, paddr += HAL_PAGE_SIZE) { + hal_vmm_unmap_page(cr3phys, (uint64_t)vaddr, (uint64_t)paddr); } spinlock_release(&spinlock); } -void hal_vmm_map_kern(PgTable *cr3) { - PgTable *kcr3 = BOOT_INFO.hhdm_off + KERNEL_CR3; +void hal_vmm_map_kern(uint64_t targetcr3) { + uint64_t *kcr3 = (uint64_t *)VIRT(KERNEL_CR3); + uint64_t *cr3 = (uint64_t *)VIRT(targetcr3); 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) { - hal_loadpd(cr3); -} - -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 hal_vmm_userproc_pml4_phys(Proc *proc) { + uint8_t *cr3phys = pmm_alloc(1); + uint64_t phys = (uint64_t)cr3phys; + hal_memset(VIRT(phys), 0, HAL_PAGE_SIZE); + uint64_t *kcr3 = (uint64_t *)VIRT(KERNEL_CR3); + uint64_t *pml4 = (uint64_t *)VIRT(phys); for (size_t i = 256; i < 512; i++) { - pml4->ents[i] = kcr3->ents[i]; + pml4[i] = kcr3[i]; } - - return (PgTable *)cr3; + return phys; } void hal_vmm_init(void) { diff --git a/kernel/hal/x86_64/vmm.h b/kernel/hal/x86_64/vmm.h index 17ba9a0..5f1aa1e 100644 --- a/kernel/hal/x86_64/vmm.h +++ b/kernel/hal/x86_64/vmm.h @@ -26,10 +26,14 @@ enum { }; typedef struct { - uint64_t pml4; - uint64_t pml3; - uint64_t pml2; - uint64_t pml1; + uint16_t pml4; + uint16_t pml3; + uint16_t pml2; + uint16_t pml1; + /* uint64_t pml4; */ + /* uint64_t pml3; */ + /* uint64_t pml2; */ + /* uint64_t pml1; */ } PACKED PgIndex; typedef struct { @@ -39,25 +43,32 @@ typedef struct { bool writethrough: 1; bool cachedisabled: 1; bool accessed: 1; - bool zero0: 1; - bool size: 1; - bool zero1: 1; + bool dirty: 1; + bool hugepage: 1; + bool global: 1; 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; typedef struct { Pte ents[512]; } PACKED PgTable; -extern PgTable *KERNEL_CR3; +extern uint64_t KERNEL_CR3; void hal_vmm_init(void); -void hal_vmm_unmap_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr); -void hal_vmm_map_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr, uint32_t flags); -PgTable *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_unmap_range(PgTable *cr3, void *virtstart, void *physstart, size_t size); -PgTable *hal_vmm_userproc_pml4(struct Proc *proc); +void hal_vmm_unmap_page(uint64_t cr3phys, uint64_t virtaddr, uint64_t physaddr); +void hal_vmm_map_page(uint64_t cr3phys, uint64_t virtaddr, uint64_t physaddr, uint32_t flags); +uint64_t hal_vmm_current_cr3(void); +void hal_vmm_map_range(uint64_t cr3phys, void *virtstart, void *physstart, size_t size, uint32_t flags); +void hal_vmm_unmap_range(uint64_t cr3phys, void *virtstart, void *physstart, size_t size); +uint64_t hal_vmm_userproc_pml4_phys(struct Proc *proc); #endif // HAL_VMM_H_ diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index 1f49cdc..e6b3fe8 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -34,7 +34,6 @@ bool proc_checkelf(uint8_t *elf) { } ElfAuxval proc_load_elf_segs(Proc *proc, uint8_t *data) { - PgTable *vas = proc->platformdata.cr3; ElfAuxval aux = {0}; Elf64_Ehdr *elfhdr = (Elf64_Ehdr *)data; @@ -51,16 +50,16 @@ ElfAuxval proc_load_elf_segs(Proc *proc, uint8_t *data) { } break; case PT_LOAD: { 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 *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); 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)); range->virtstart = virtaddr; @@ -89,15 +88,15 @@ Proc *proc_spawnkern(void (*ent)(void), char *name) { 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; proc->platformdata.kstack = kstackp; - proc->platformdata.pstack = sp; + proc->platformdata.pstack = pstackp; hal_memset(&proc->platformdata.trapframe, 0, sizeof(proc->platformdata.trapframe)); 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.cs = 0x08; proc->platformdata.trapframe.rip = (uint64_t)ent; @@ -144,31 +143,50 @@ Proc *proc_spawnuser(char *mountpoint, char *path) { Proc *proc = dlmalloc(sizeof(*proc)); hal_memset(proc, 0, sizeof(*proc)); ksprintf(proc->name, "%s:%s", mountpoint, path); + + hal_memset(&proc->platformdata.trapframe, 0, sizeof(proc->platformdata.trapframe)); + proc->platformdata.cr3 = hal_vmm_userproc_pml4_phys(proc); - 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; + uint8_t *pstackp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS); + proc->platformdata.pstack = pstackp; - hal_memset(&proc->platformdata.trapframe, 0, sizeof(proc->platformdata.trapframe)); - - proc->platformdata.cr3 = hal_vmm_userproc_pml4(proc); + uint64_t virttop = PROC_USER_STACK_TOP; + uint64_t virtbase = virttop - PROC_STACKSIZE; - uint32_t flags = HAL_PG_RW | HAL_PG_USER | HAL_PG_PRESENT; + 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); - 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->virtstart = (uint8_t *)virtbase; + range->physstart = (uint8_t *)pstackp; range->size = PROC_STACKSIZE; range->pgflags = flags; 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); 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.cs = 0x18 | 0x3; proc->platformdata.trapframe.rip = aux.entry; @@ -206,6 +224,7 @@ Proc *proc_nextready(void) { } void proc_reaper(void) { + spinlock_acquire(&PROCS.spinlock); Proc *head = PROCS.procs; while (head) { if (head->state == PROC_ZOMBIE) { @@ -221,13 +240,13 @@ void proc_reaper(void) { } } - /* for (size_t i = 0; i < PROC_PIPEHANDLES_MAX; i++) { */ - /* if (zombie->pipes[i] != NULL && zombie->pipes[i]->ownerpid == zombie->pid) { */ - /* dlfree(zombie->pipes[i]); */ - /* ipc_pipefree(zombie->pipes[i]); */ - /* zombie->pipes[i] = NULL; */ - /* } */ - /* } */ + for (size_t i = 0; i < PROC_PIPEHANDLES_MAX; i++) { + if (zombie->pipes[i] != NULL && zombie->pipes[i]->ownerpid == zombie->pid) { + dlfree(zombie->pipes[i]); + ipc_pipefree(zombie->pipes[i]); + zombie->pipes[i] = NULL; + } + } pmm_free((uintptr_t)(zombie->platformdata.kstack - 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) { VasRange *tmp = vashead; vashead = vashead->next; - hal_vmm_unmap_range(VIRT(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); - } + hal_vmm_unmap_range(zombie->platformdata.cr3, tmp->virtstart, tmp->physstart, tmp->size); + pmm_free((uintptr_t)tmp->physstart, tmp->size / HAL_PAGE_SIZE); dlfree(tmp); i++; } @@ -262,6 +278,7 @@ void proc_reaper(void) { head = head->next; } } + spinlock_release(&PROCS.spinlock); } void proc_sched(void *cpustate) { diff --git a/kernel/proc/proc.h b/kernel/proc/proc.h index 9d3ec70..b88237b 100644 --- a/kernel/proc/proc.h +++ b/kernel/proc/proc.h @@ -11,7 +11,7 @@ #define PROC_NAME_MAX 0x100 -#define PROC_STACKBLOCKS 32 +#define PROC_STACKBLOCKS 256 #define PROC_STACKSIZE (PROC_STACKBLOCKS * BITMAP_BLOCK_SIZE) #define PROC_MAX 0x100 // max amount of processes @@ -19,13 +19,14 @@ #define PROC_VFSHANDLES_MAX 0x80 #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 { IntrStackFrame trapframe; uint8_t *kstack; uint8_t *pstack; - PgTable *cr3; + uint64_t cr3; } ProcPlatformData; enum { @@ -33,6 +34,7 @@ enum { PROC_READY = 1, PROC_ZOMBIE = 2, PROC_WAITING = 3, + PROC_DIED = 4, }; typedef struct ProcArg { diff --git a/kernel/syscall/mman.c b/kernel/syscall/mman.c index 5b59721..4cc580c 100644 --- a/kernel/syscall/mman.c +++ b/kernel/syscall/mman.c @@ -18,7 +18,7 @@ int32_t SYSCALL5(sys_mman_map, addr1, size1, prot1, flags1, out1) { uint64_t flags = flags1; uint8_t **out = (uint8_t **)out1; - if (size % HAL_PAGE_SIZE != 0) { + if (size == 0 || (size % HAL_PAGE_SIZE != 0)) { if (out != NULL) { *out = NULL; } @@ -37,11 +37,19 @@ int32_t SYSCALL5(sys_mman_map, addr1, size1, prot1, flags1, out1) { spinlock_release(&PROCS.spinlock); 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; } else { 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; @@ -49,11 +57,11 @@ int32_t SYSCALL5(sys_mman_map, addr1, size1, prot1, flags1, out1) { 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)); range->virtstart = virt; range->physstart = phys; - range->size = size * HAL_PAGE_SIZE; + range->size = pages * HAL_PAGE_SIZE; range->pgflags = pflags; LL_APPEND(proc->vas, range); @@ -91,7 +99,7 @@ int32_t SYSCALL1(sys_mman_unmap, addr1) { 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); pmm_free((uintptr_t)tofree->physstart, tofree->size / HAL_PAGE_SIZE); dlfree(tofree); diff --git a/kernel/syscall/processctl.c b/kernel/syscall/processctl.c index 0785379..310c60b 100644 --- a/kernel/syscall/processctl.c +++ b/kernel/syscall/processctl.c @@ -29,7 +29,7 @@ int32_t SYSCALL5(sys_processctl, pid1, cmd1, arg1, arg2, arg3) { if (proc == NULL) { if (cmd == PCTL_POLLSTATE) { - ret = 2; + ret = PROC_DIED; goto done; } ret = E_INVALIDARGUMENT; @@ -104,6 +104,44 @@ int32_t SYSCALL5(sys_processctl, pid1, cmd1, arg1, arg2, arg3) { } ret = E_OK; } 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: { ret = E_INVALIDARGUMENT; } break; diff --git a/mk/user/x86_64.mk b/mk/user/x86_64.mk index 8379193..9b7bf51 100644 --- a/mk/user/x86_64.mk +++ b/mk/user/x86_64.mk @@ -1,5 +1,4 @@ CFLAGS += -m64 \ - -fPIE \ -mno-80387 \ -mno-mmx \ -mno-sse \ diff --git a/share/sysdefs/processctl.h b/share/sysdefs/processctl.h index fd62551..cde07fd 100644 --- a/share/sysdefs/processctl.h +++ b/share/sysdefs/processctl.h @@ -11,6 +11,16 @@ enum { PCTL_GETPID = 4, PCTL_ARGLEN = 5, 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_ diff --git a/ulib/_premain.c b/ulib/_premain.c index cbd5e15..6e41e27 100644 --- a/ulib/_premain.c +++ b/ulib/_premain.c @@ -8,11 +8,10 @@ #include extern void main(void); +extern uint8_t _bss_start; +extern uint8_t _bss_end; void clearbss(void) { - extern uint8_t _bss_start; - extern uint8_t _bss_end; - uint8_t *ps = &_bss_start; uint8_t *pe = &_bss_end; size_t sz = pe - ps; diff --git a/ulib/dlmalloc/dlmalloc_port.inc b/ulib/dlmalloc/dlmalloc_port.inc index 8ada055..9f222b4 100644 --- a/ulib/dlmalloc/dlmalloc_port.inc +++ b/ulib/dlmalloc/dlmalloc_port.inc @@ -46,7 +46,7 @@ int RELEASE_LOCK(SpinLock *sl) { } int INITIAL_LOCK(SpinLock *sl) { - spinlock_release(sl); + spinlock_init(sl); return 0; } @@ -79,12 +79,17 @@ void *sbrk(ptrdiff_t inc) { return heap_end; } - uint8_t *oldh = heap_end; - uint8_t *newh = heap_end + inc; + uint8_t *oldbrk = heap_end; + uint8_t *newbrk = heap_end + inc; + + if (newbrk < heap_start) { + return (void *)-1; + } if (inc > 0) { - if (newh > heap_commit) { - size_t extra = _roundpage((size_t)(newh - heap_commit)); + if (newbrk > heap_commit) { + size_t need = (size_t)(newbrk - heap_commit); + size_t extra = _roundpage(need); uint8_t *maddr = NULL; int32_t ret = mman_map(NULL, extra, MMAN_MAP_PF_RW, 0, &maddr); if (ret != E_OK || maddr == NULL) { @@ -92,39 +97,7 @@ void *sbrk(ptrdiff_t inc) { } heap_commit += extra; } - heap_end = newh; - } else { - heap_end = newh; } - return oldh; - - #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 + heap_end = newbrk; + return (void *)oldbrk; } diff --git a/user/arch/x86_64/link.ld b/user/arch/x86_64/link.ld index f3f72b5..5f7ec45 100644 --- a/user/arch/x86_64/link.ld +++ b/user/arch/x86_64/link.ld @@ -1,7 +1,7 @@ ENTRY(_start) SECTIONS { - /* . = 0x0000000000000000; */ + . = 0x400000; .text ALIGN(4K): { diff --git a/user/arch/x86_64/x86_64.mk b/user/arch/x86_64/x86_64.mk index ceee098..79c7562 100644 --- a/user/arch/x86_64/x86_64.mk +++ b/user/arch/x86_64/x86_64.mk @@ -2,7 +2,6 @@ include $(ROOT)/mk/user/x86_64.mk include $(ROOT)/mk/arch/toolchain-x86_64.mk LDFLAGS += -m elf_x86_64 \ - -pie \ --no-dynamic-linker \ -z text \ -z max-page-size=0x1000 diff --git a/user/init/main.c b/user/init/main.c index 59a366a..606516a 100644 --- a/user/init/main.c +++ b/user/init/main.c @@ -7,18 +7,37 @@ #include #include #include +#include + +#define SUBPROC_PIPE_OUT 0x1f + +uint64_t PID; 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" }; 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 *)selfpid, IPCPIPE_OUT); - processctl(tb, PCTL_RUN, 0, 0, 0); + ipcpipe(tb, IPCPIPE_OUT, IPCPIPE_REPLACE, (uint8_t *)PID, SUBPROC_PIPE_OUT); ipcpipe(IPCPIPE_SELFPID, 10, IPCPIPE_MAKE, NULL, 0); ipcpipe(IPCPIPE_SELFPID, 10, IPCPIPE_ADD_BCAST, NULL, 1); + + processctl(tb, PCTL_RUN, 0, 0, 0); - while(processctl(tb, PCTL_POLLSTATE, 0, 0, 0) != 2) { + #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 read = ipcpipe(IPCPIPE_SELFPID, 10, IPCPIPE_READ, (uint8_t *)&kbchr, sizeof(kbchr)); if (read > 0) { @@ -32,6 +51,9 @@ void main(void) { } } } +#endif } + + for(;;); } diff --git a/user/pctl/Makefile b/user/pctl/Makefile new file mode 100644 index 0000000..0d1b960 --- /dev/null +++ b/user/pctl/Makefile @@ -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) diff --git a/user/pctl/main.c b/user/pctl/main.c new file mode 100644 index 0000000..ec0eb95 --- /dev/null +++ b/user/pctl/main.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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"); + } +} diff --git a/user/pctl/main.o b/user/pctl/main.o new file mode 100644 index 0000000..2bdef2c Binary files /dev/null and b/user/pctl/main.o differ diff --git a/user/pctl/pctl b/user/pctl/pctl new file mode 100755 index 0000000..56c0d4a Binary files /dev/null and b/user/pctl/pctl differ diff --git a/user/tb/interp.c b/user/tb/interp.c index 87cfc0a..2afab06 100644 --- a/user/tb/interp.c +++ b/user/tb/interp.c @@ -5,10 +5,17 @@ #include #include #include +#include +#include +#include #include #include "interp.h" #include "runtime.h" +#define SUBPROC_PIPE_OUT 0x1f + +extern uint64_t PID; + static InterpResult RES; void tz_init(Tokenizer *tz, const char *str, size_t len) { @@ -62,7 +69,7 @@ void tz_classify(Tokenizer *tz) { while (tk) { if (tk->ptr[0] == '"' && tk->ptr[tk->len - 1] == '"') { tk->type = TOK_STRING; - } else { + } else if (tk->ptr[0] == '@') { RtCmd *cmd = RTCMDS; while (cmd) { char tmpbuf[0xff] = {0}; @@ -74,6 +81,8 @@ void tz_classify(Tokenizer *tz) { } cmd = cmd->next; } + } else { + tk->type = TOK_MISC; } tk = tk->next; } @@ -132,8 +141,9 @@ bool interp_readline(char *data, const char **bgptr, const char **endptr) { return true; } -bool interp_runstring(const char *string, size_t len, InterpResult **res) { +bool interp_runstring(const char *string, InterpResult **res) { *res = &RES; + string_memset(RES.errmsg, 0, sizeof(RES.errmsg)); rt_init(); bool ok = true; @@ -156,19 +166,62 @@ bool interp_runstring(const char *string, size_t len, InterpResult **res) { tz_classify(&tz); Token *cmdtk = tz.tokens; - 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; - } + if (cmdtk->type == TOK_CMD) { + ok = cmdtk->cmd->fn(cmdtk->next); + if (!ok) { + ok = false; + usprintf(RES.errmsg, "cmd %.*s failed", (int)cmdtk->len, cmdtk->ptr); + tz_free(&tz); + goto done; + } + } else if (cmdtk->type == TOK_MISC) { + char *appname = dlmalloc(1024); + usprintf(appname, "%.*s", (int)cmdtk->len, cmdtk->ptr); - ok = cmdtk->cmd->fn(cmdtk->next); - if (!ok) { - ok = false; - usprintf(RES.errmsg, "cmd %.*s failed", (int)cmdtk->len, cmdtk->ptr); - tz_free(&tz); - goto done; + 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); diff --git a/user/tb/interp.h b/user/tb/interp.h index 28cb826..01c5537 100644 --- a/user/tb/interp.h +++ b/user/tb/interp.h @@ -19,6 +19,7 @@ typedef struct Token { enum { TOK_STRING, TOK_CMD, + TOK_MISC, } type; struct RtCmd *cmd; @@ -32,6 +33,6 @@ typedef struct { Token *tokens; } Tokenizer; -bool interp_runstring(const char *string, size_t len, InterpResult **res); +bool interp_runstring(const char *string, InterpResult **res); #endif // TB_INTERP_H_ diff --git a/user/tb/main.c b/user/tb/main.c index eb76bc4..169eaba 100644 --- a/user/tb/main.c +++ b/user/tb/main.c @@ -15,6 +15,8 @@ #include #include "interp.h" +uint64_t PID; + struct { char *modestr; 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); 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) { 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; - bool ok = interp_runstring((const char *)buf, statbuf.size, &res); + bool ok = interp_runstring((const char *)buf, &res); if (!ok) { uprintf("Interpreter error:\n"); uprintf("%s\n", res->errmsg); @@ -105,10 +108,16 @@ void do_mode_interactive(void) { } linebuf[cursor - 1] = '\0'; uprintf("\n"); + InterpResult *res; + if (!interp_runstring(linebuf, &res)) { + LOG(LOG_ERR, "%s\n", res->errmsg); + } } } void main(void) { + PID = processctl(-1, PCTL_GETPID, 0, 0, 0); + set_config(); if (CONFIG.mode == MODE_INTERACTIVE) { diff --git a/user/tb/runtime.c b/user/tb/runtime.c index 4957b71..769e0e1 100644 --- a/user/tb/runtime.c +++ b/user/tb/runtime.c @@ -8,11 +8,11 @@ RtCmd *RTCMDS = NULL; -#define RTCMD(name) \ +#define RTCMD(name, _fn) \ do { \ RtCmd *_cmd = dlmalloc(sizeof(*_cmd)); \ - _cmd->cmdname = #name; \ - _cmd->fn = rt_##name; \ + _cmd->cmdname = (name); \ + _cmd->fn = (_fn); \ LL_APPEND(RTCMDS, _cmd); \ } while(0) @@ -25,10 +25,10 @@ bool rt_print(Token *tks) { } tk = tk->next; } - + uprintf("\n"); return true; } void rt_init(void) { - RTCMD(print); + RTCMD("@print", &rt_print); }