summaryrefslogtreecommitdiff
path: root/proc.c
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2019-05-31 12:43:20 -0400
committerRobert Morris <[email protected]>2019-05-31 12:43:20 -0400
commit7fd1f1eb0aab4d52852fc4f5e83eafc991f9a627 (patch)
tree321ae7c509d2b6286240ad181bc28a9dc3436704 /proc.c
parent5d34fa2a489940f19ee6c4728e4b11b6d8ffad01 (diff)
downloadxv6-labs-7fd1f1eb0aab4d52852fc4f5e83eafc991f9a627.tar.gz
xv6-labs-7fd1f1eb0aab4d52852fc4f5e83eafc991f9a627.tar.bz2
xv6-labs-7fd1f1eb0aab4d52852fc4f5e83eafc991f9a627.zip
exec compiles but argstr() doesn't work yet
Diffstat (limited to 'proc.c')
-rw-r--r--proc.c50
1 files changed, 38 insertions, 12 deletions
diff --git a/proc.c b/proc.c
index a099e98..f0120c2 100644
--- a/proc.c
+++ b/proc.c
@@ -94,26 +94,54 @@ found:
}
// An empty user page table.
- p->pagetable = uvmcreate();
+ p->pagetable = proc_pagetable(p);
+
+ // Set up new context to start executing at forkret,
+ // which returns to user space.
+ memset(&p->context, 0, sizeof p->context);
+ p->context.ra = (uint64)forkret;
+ p->context.sp = (uint64)p->kstack + PGSIZE;
+
+ return p;
+}
+
+// Create a page table for a given process,
+// with no users pages, but with trampoline pages.
+// Called both when creating a process, and
+// by exec() when building tentative new memory image,
+// which might fail.
+pagetable_t
+proc_pagetable(struct proc *p)
+{
+ pagetable_t pagetable;
+
+ // An empty user page table.
+ pagetable = uvmcreate();
// map the trampoline code (for system call return)
// at the highest user virtual address.
// only the supervisor uses it, on the way
// to/from user space, so not PTE_U.
- mappages(p->pagetable, TRAMPOLINE, PGSIZE,
+ mappages(pagetable, TRAMPOLINE, PGSIZE,
(uint64)trampstart, PTE_R | PTE_X);
// map the trapframe, for trampoline.S.
- mappages(p->pagetable, (TRAMPOLINE - PGSIZE), PGSIZE,
+ mappages(pagetable, (TRAMPOLINE - PGSIZE), PGSIZE,
(uint64)(p->tf), PTE_R | PTE_W);
- // Set up new context to start executing at forkret,
- // which returns to user space.
- memset(&p->context, 0, sizeof p->context);
- p->context.ra = (uint64)forkret;
- p->context.sp = (uint64)p->kstack + PGSIZE;
+ return pagetable;
+}
- return p;
+// Free a process's page table, and free the
+// physical memory the page table refers to.
+// Called both when a process exits and from
+// exec() if it fails.
+void
+proc_freepagetable(pagetable_t pagetable, uint64 sz)
+{
+ unmappages(pagetable, TRAMPOLINE, PGSIZE, 0);
+ unmappages(pagetable, TRAMPOLINE-PGSIZE, PGSIZE, 0);
+ uvmfree(pagetable, sz);
}
// a user program that calls exec("/init")
@@ -295,9 +323,7 @@ wait(void)
np->kstack = 0;
kfree((void*)np->tf);
np->tf = 0;
- unmappages(np->pagetable, TRAMPOLINE, PGSIZE, 0);
- unmappages(np->pagetable, TRAMPOLINE-PGSIZE, PGSIZE, 0);
- uvmfree(np->pagetable, np->sz);
+ proc_freepagetable(np->pagetable, np->sz);
np->pagetable = 0;
np->pid = 0;
np->parent = 0;