summaryrefslogtreecommitdiff
path: root/proc.c
diff options
context:
space:
mode:
authorFrans Kaashoek <[email protected]>2010-07-02 14:51:53 -0400
committerFrans Kaashoek <[email protected]>2010-07-02 14:51:53 -0400
commit40889627ba50db29a64bc6a1553c2b21e6a99b78 (patch)
tree7cb8f51492af706cafdcaf1b01a5cac8073d5a38 /proc.c
parentb7a517f2277670e156f150ee2cb7aae6426c6aef (diff)
downloadxv6-labs-40889627ba50db29a64bc6a1553c2b21e6a99b78.tar.gz
xv6-labs-40889627ba50db29a64bc6a1553c2b21e6a99b78.tar.bz2
xv6-labs-40889627ba50db29a64bc6a1553c2b21e6a99b78.zip
Initial version of single-cpu xv6 with page tables
Diffstat (limited to 'proc.c')
-rw-r--r--proc.c72
1 files changed, 15 insertions, 57 deletions
diff --git a/proc.c b/proc.c
index 669331e..a38a9e6 100644
--- a/proc.c
+++ b/proc.c
@@ -60,39 +60,6 @@ procdump(void)
}
}
-// Set up CPU's kernel segment descriptors.
-// Run once at boot time on each CPU.
-void
-ksegment(void)
-{
- struct cpu *c;
-
- c = &cpus[cpunum()];
- c->gdt[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0x100000 + 64*1024-1, 0);
- c->gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0);
- c->gdt[SEG_KCPU] = SEG(STA_W, &c->cpu, 8, 0);
- lgdt(c->gdt, sizeof(c->gdt));
- loadgs(SEG_KCPU << 3);
-
- // Initialize cpu-local storage.
- cpu = c;
- proc = 0;
-}
-
-// Set up CPU's segment descriptors and current process task state.
-void
-usegment(void)
-{
- pushcli();
- cpu->gdt[SEG_UCODE] = SEG(STA_X|STA_R, proc->mem, proc->sz-1, DPL_USER);
- cpu->gdt[SEG_UDATA] = SEG(STA_W, proc->mem, proc->sz-1, DPL_USER);
- cpu->gdt[SEG_TSS] = SEG16(STS_T32A, &cpu->ts, sizeof(cpu->ts)-1, 0);
- cpu->gdt[SEG_TSS].s = 0;
- cpu->ts.ss0 = SEG_KDATA << 3;
- cpu->ts.esp0 = (uint)proc->kstack + KSTACKSIZE;
- ltr(SEG_TSS << 3);
- popcli();
-}
//PAGEBREAK: 32
// Look in the process table for an UNUSED proc.
@@ -149,20 +116,19 @@ userinit(void)
p = allocproc();
initproc = p;
-
- // Initialize memory from initcode.S
- p->sz = PAGE;
- p->mem = kalloc(p->sz);
- memset(p->mem, 0, p->sz);
- memmove(p->mem, _binary_initcode_start, (int)_binary_initcode_size);
-
+ if (!(p->pgdir = setupkvm()))
+ panic("userinit: out of memory?");
+ if (!allocuvm(p->pgdir, 0x0, (int)_binary_initcode_size))
+ panic("userinit: out of memory?");
+ inituvm(p->pgdir, 0x0, _binary_initcode_start, (int)_binary_initcode_size);
+ p->sz = PGROUNDUP((int)_binary_initcode_size);
memset(p->tf, 0, sizeof(*p->tf));
p->tf->cs = (SEG_UCODE << 3) | DPL_USER;
p->tf->ds = (SEG_UDATA << 3) | DPL_USER;
p->tf->es = p->tf->ds;
p->tf->ss = p->tf->ds;
p->tf->eflags = FL_IF;
- p->tf->esp = p->sz;
+ p->tf->esp = PGSIZE;
p->tf->eip = 0; // beginning of initcode.S
safestrcpy(p->name, "initcode", sizeof(p->name));
@@ -176,17 +142,10 @@ userinit(void)
int
growproc(int n)
{
- char *newmem;
-
- newmem = kalloc(proc->sz + n);
- if(newmem == 0)
+ if (!allocuvm(proc->pgdir, (char *)proc->sz, n))
return -1;
- memmove(newmem, proc->mem, proc->sz);
- memset(newmem + proc->sz, 0, n);
- kfree(proc->mem, proc->sz);
- proc->mem = newmem;
proc->sz += n;
- usegment();
+ loadvm(proc);
return 0;
}
@@ -204,14 +163,13 @@ fork(void)
return -1;
// Copy process state from p.
- np->sz = proc->sz;
- if((np->mem = kalloc(np->sz)) == 0){
+ if (!(np->pgdir = copyuvm(proc->pgdir, proc->sz))) {
kfree(np->kstack, KSTACKSIZE);
np->kstack = 0;
np->state = UNUSED;
return -1;
}
- memmove(np->mem, proc->mem, np->sz);
+ np->sz = proc->sz;
np->parent = proc;
*np->tf = *proc->tf;
@@ -225,7 +183,7 @@ fork(void)
pid = np->pid;
np->state = RUNNABLE;
-
+ safestrcpy(np->name, proc->name, sizeof(proc->name));
return pid;
}
@@ -256,7 +214,7 @@ scheduler(void)
// to release ptable.lock and then reacquire it
// before jumping back to us.
proc = p;
- usegment();
+ loadvm(p);
p->state = RUNNING;
swtch(&cpu->scheduler, proc->context);
@@ -284,7 +242,6 @@ sched(void)
panic("sched running");
if(readeflags()&FL_IF)
panic("sched interruptible");
-
intena = cpu->intena;
swtch(&proc->context, cpu->scheduler);
cpu->intena = intena;
@@ -455,9 +412,10 @@ wait(void)
if(p->state == ZOMBIE){
// Found one.
pid = p->pid;
- kfree(p->mem, p->sz);
kfree(p->kstack, KSTACKSIZE);
+ freevm(p->pgdir);
p->state = UNUSED;
+ p->kstack = 0;
p->pid = 0;
p->parent = 0;
p->name[0] = 0;