summaryrefslogtreecommitdiff
path: root/vm.c
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2019-06-01 05:33:38 -0400
committerRobert Morris <[email protected]>2019-06-01 05:33:38 -0400
commit50cbc7510250a64674d619d13f5912edf08b767d (patch)
tree874895d11adb72fed959619d85596b062260276f /vm.c
parent7fd1f1eb0aab4d52852fc4f5e83eafc991f9a627 (diff)
downloadxv6-labs-50cbc7510250a64674d619d13f5912edf08b767d.tar.gz
xv6-labs-50cbc7510250a64674d619d13f5912edf08b767d.tar.bz2
xv6-labs-50cbc7510250a64674d619d13f5912edf08b767d.zip
first shell prints $ prompt, though no console input yet
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c76
1 files changed, 72 insertions, 4 deletions
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;
+ }
+}