From 50cbc7510250a64674d619d13f5912edf08b767d Mon Sep 17 00:00:00 2001 From: Robert Morris Date: Sat, 1 Jun 2019 05:33:38 -0400 Subject: first shell prints $ prompt, though no console input yet --- vm.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 4 deletions(-) (limited to 'vm.c') diff --git a/vm.c b/vm.c index 27fb690..791f78f 100644 --- a/vm.c +++ b/vm.c @@ -13,7 +13,7 @@ pagetable_t kernel_pagetable; extern char etext[]; // kernel.ld sets this to end of kernel code. -extern char trampstart[]; // trampoline.S +extern char trampout[]; // trampoline.S /* * create a direct-map page table for the kernel and @@ -45,7 +45,7 @@ kvminit() // map the trampoline for trap entry/exit to // the highest virtual address in the kernel. mappages(kernel_pagetable, TRAMPOLINE, PGSIZE, - (uint64)trampstart, PTE_R | PTE_X); + (uint64)trampout, PTE_R | PTE_X); kvmswitch(); } @@ -213,7 +213,7 @@ uvmalloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz) return 0; } memset(mem, 0, PGSIZE); - mappages(pagetable, a, PGSIZE, (uint64)mem, PTE_W|PTE_X|PTE_R); + mappages(pagetable, a, PGSIZE, (uint64)mem, PTE_W|PTE_X|PTE_R|PTE_U); } return newsz; } @@ -287,8 +287,8 @@ uvmcopy(pagetable_t old, pagetable_t new, uint64 sz) } } +// Copy from kernel to user. // Copy len bytes from src to virtual address dstva in a given page table. -// Most useful when pagetable is not the current page table. // Return 0 on success, -1 on error. int copyout(pagetable_t pagetable, uint64 dstva, char *src, uint64 len) @@ -311,3 +311,71 @@ copyout(pagetable_t pagetable, uint64 dstva, char *src, uint64 len) } return 0; } + +// Copy from user to kernel. +// Copy len bytes to dst from virtual address srcva in a given page table. +// Return 0 on success, -1 on error. +int +copyin(pagetable_t pagetable, char *dst, uint64 srcva, uint64 len) +{ + uint64 n, va0, pa0; + + while(len > 0){ + va0 = (uint)PGROUNDDOWN(srcva); + pa0 = walkaddr(pagetable, va0); + if(pa0 == 0) + return -1; + n = PGSIZE - (srcva - va0); + if(n > len) + n = len; + memmove(dst, (void *)(pa0 + (srcva - va0)), n); + + len -= n; + dst += n; + srcva = va0 + PGSIZE; + } + return 0; +} + +// Copy a null-terminated from user to kernel. +// Copy bytes to dst from virtual address srcva in a given page table, +// until a '\0', or max. +// Return 0 on success, -1 on error. +int +copyinstr(pagetable_t pagetable, char *dst, uint64 srcva, uint64 max) +{ + uint64 n, va0, pa0; + int got_null = 0; + + while(got_null == 0 && max > 0){ + va0 = (uint)PGROUNDDOWN(srcva); + pa0 = walkaddr(pagetable, va0); + if(pa0 == 0) + return -1; + n = PGSIZE - (srcva - va0); + if(n > max) + n = max; + + char *p = (char *) (pa0 + (srcva - va0)); + while(n > 0){ + if(*p == '\0'){ + *dst = '\0'; + got_null = 1; + break; + } else { + *dst = *p; + } + --n; + --max; + p++; + dst++; + } + + srcva = va0 + PGSIZE; + } + if(got_null){ + return 0; + } else { + return -1; + } +} -- cgit v1.2.3