summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorrsc <rsc>2007-08-21 19:22:08 +0000
committerrsc <rsc>2007-08-21 19:22:08 +0000
commitf32f3638f4c34fbf2fc4398878e6304612bb3283 (patch)
treecabca9bf9ac8b1465b2c59e27e3dc8020c02e2be /main.c
parent2d61a40b2059b9a198e7c4ff04c6ced88cb3ce65 (diff)
downloadxv6-labs-f32f3638f4c34fbf2fc4398878e6304612bb3283.tar.gz
xv6-labs-f32f3638f4c34fbf2fc4398878e6304612bb3283.tar.bz2
xv6-labs-f32f3638f4c34fbf2fc4398878e6304612bb3283.zip
Various cleanup:
- Got rid of dummy proc[0]. Now proc[0] is init. - Added initcode.S to exec /init, so that /init is just a regular binary. - Moved exec out of sysfile to exec.c - Moved code dealing with fs guts (like struct inode) from sysfile.c to fs.c. Code dealing with system call arguments stays in sysfile.c - Refactored directory routines in fs.c; should be simpler. - Changed iget to return *unlocked* inode structure. This solves the lookup-then-use race in namei without introducing deadlocks. It also enabled getting rid of the dummy proc[0].
Diffstat (limited to 'main.c')
-rw-r--r--main.c120
1 files changed, 40 insertions, 80 deletions
diff --git a/main.c b/main.c
index fb7a69a..2774636 100644
--- a/main.c
+++ b/main.c
@@ -11,9 +11,8 @@
#include "spinlock.h"
extern char edata[], end[];
-extern uchar _binary__init_start[], _binary__init_size[];
-void process0();
+void proc0init();
// Bootstrap processor starts running C code here.
// This is called main0 not main so that it can have
@@ -24,7 +23,6 @@ main0(void)
{
int i;
static int bcpu; // cannot be on stack
- struct proc *p;
// clear BSS
memset(edata, 0, end - edata);
@@ -54,15 +52,6 @@ main0(void)
fileinit();
iinit(); // i-node table
- // initialize process 0
- p = &proc[0];
- p->state = RUNNABLE;
- p->kstack = kalloc(KSTACKSIZE);
-
- // cause proc[0] to start in kernel at process0
- p->jmpbuf.eip = (uint) process0;
- p->jmpbuf.esp = (uint) (p->kstack + KSTACKSIZE - 4);
-
// make sure there's a TSS
setupsegs(0);
@@ -86,6 +75,9 @@ main0(void)
cpus[cpu()].nlock--;
sti();
+ // initialize process 0
+ proc0init();
+
scheduler();
}
@@ -114,77 +106,45 @@ mpmain(void)
scheduler();
}
-// proc[0] starts here, called by scheduler() in the ordinary way.
+char initcode[] = {
+ /* push ptr to argv */ 0x6a, 0x1c,
+ /* push ptr to "/init" */ 0x6a, 0x16,
+ /* push fake ret addr */ 0x6a, 0x00,
+ /* mov $SYS_exec, %eax */ 0xb8, 0x09, 0x00, 0x00, 0x00,
+ /* int $0x30 */ 0xcd, 0x30,
+ /* Lx: */
+ /* mov $SYS_exit, %eax */ 0xb8, 0x02, 0x00, 0x00, 0x00,
+ /* int $0x30 */ 0xcd, 0x30,
+ /* jmp Lx */ 0xeb, 0xf7,
+
+ /* "/init\0" */ 0x2f, 0x69, 0x6e, 0x69, 0x74, 0x00,
+ /* ptr to "/init" */ 0x16, 0x00, 0x00, 0x00,
+ /* 0 */ 0x00, 0x00, 0x00, 0x00
+};
+
void
-process0(void)
+proc0init(void)
{
- extern struct spinlock proc_table_lock;
- struct proc *p0, *p1;
- struct trapframe tf;
-
- release(&proc_table_lock);
-
- p0 = &proc[0];
- p0->cwd = igetroot();
- iunlock(p0->cwd);
-
- // Dummy user memory to make copyproc() happy.
- // Must be big enough to hold the init binary and stack.
- p0->sz = 2*PAGE;
- p0->mem = kalloc(p0->sz);
-
- // Fake a trap frame as if a user process had made a system
- // call, so that copyproc will have a place for the new
- // process to return to.
- p0->tf = &tf;
- memset(p0->tf, 0, sizeof(struct trapframe));
- p0->tf->es = p0->tf->ds = p0->tf->ss = (SEG_UDATA << 3) | DPL_USER;
- p0->tf->cs = (SEG_UCODE << 3) | DPL_USER;
- p0->tf->eflags = FL_IF;
- p0->tf->esp = p0->sz;
+ struct proc *p;
+ extern uchar _binary_initcode_start[], _binary_initcode_size[];
- // Push bogus return address, both to cause problems
- // if main returns and also because gcc can generate
- // function prologs that expect to be able to read the
- // return address off the stack without causing a fault.
- p0->tf->esp -= 4;
- *(uint*)(p0->mem + p0->tf->esp) = 0xefefefef;
-
- p1 = copyproc(p0);
-
- load_icode(p1, _binary__init_start, (uint) _binary__init_size);
- p1->state = RUNNABLE;
- safestrcpy(p1->name, "init", sizeof p1->name);
+ p = copyproc(0);
+ p->sz = PAGE;
+ p->mem = kalloc(p->sz);
+ p->cwd = igetroot();
+ memset(&p->tf, 0, sizeof p->tf);
+ p->tf->es = p->tf->ds = p->tf->ss = (SEG_UDATA << 3) | DPL_USER;
+ p->tf->cs = (SEG_UCODE << 3) | DPL_USER;
+ p->tf->eflags = FL_IF;
+ p->tf->esp = p->sz;
+
+ // Push dummy return address to placate gcc.
+ p->tf->esp -= 4;
+ *(uint*)(p->mem + p->tf->esp) = 0xefefefef;
- proc_wait();
- panic("init exited");
+ p->tf->eip = 0;
+ memmove(p->mem, _binary_initcode_start, (int)_binary_initcode_size);
+ safestrcpy(p->name, "initcode", sizeof p->name);
+ p->state = RUNNABLE;
}
-void
-load_icode(struct proc *p, uchar *binary, uint size)
-{
- int i;
- struct elfhdr *elf;
- struct proghdr *ph;
-
- elf = (struct elfhdr*) binary;
- if(elf->magic != ELF_MAGIC)
- panic("load_icode: not an ELF binary");
-
- p->tf->eip = elf->entry;
-
- // Map and load segments as directed.
- ph = (struct proghdr*) (binary + elf->phoff);
- for(i = 0; i < elf->phnum; i++, ph++) {
- if(ph->type != ELF_PROG_LOAD)
- continue;
- if(ph->va + ph->memsz < ph->va)
- panic("load_icode: overflow in proghdr");
- if(ph->va + ph->memsz >= p->sz)
- panic("load_icode: icode too large");
-
- // Load/clear the segment
- memmove(p->mem + ph->va, binary + ph->offset, ph->filesz);
- memset(p->mem + ph->va + ph->filesz, 0, ph->memsz - ph->filesz);
- }
-}