From ceb0e427962d0656e672955585c04093b9efda90 Mon Sep 17 00:00:00 2001 From: rtm Date: Wed, 16 Aug 2006 01:56:00 +0000 Subject: [PATCH] proc[0] can sleep(), at least after it gets to main00() proc[0] calls iget(rootdev, 1) before forking init --- Makefile | 4 ++-- main.c | 61 +++++++++++++++++++++++++++++++++++++++----------------- proc.h | 3 +-- trap.c | 2 ++ 4 files changed, 48 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index 9a6b02d..a40289f 100644 --- a/Makefile +++ b/Makefile @@ -46,12 +46,12 @@ bootblock : bootasm.S bootmain.c $(OBJCOPY) -S -O binary bootblock.o bootblock ./sign.pl bootblock -kernel : $(OBJS) bootother.S userfs init +kernel : $(OBJS) bootother.S init $(CC) -nostdinc -I. -c bootother.S $(LD) -N -e start -Ttext 0x7000 -o bootother.out bootother.o $(OBJCOPY) -S -O binary bootother.out bootother $(OBJDUMP) -S bootother.o > bootother.asm - $(LD) -Ttext 0x100000 -e main0 -o kernel $(OBJS) -b binary bootother userfs init + $(LD) -Ttext 0x100000 -e main0 -o kernel $(OBJS) -b binary bootother init $(OBJDUMP) -S kernel > kernel.asm vectors.S : vectors.pl diff --git a/main.c b/main.c index 35ea672..9611f74 100644 --- a/main.c +++ b/main.c @@ -11,9 +11,10 @@ #include "spinlock.h" extern char edata[], end[]; -extern uchar _binary_userfs_start[], _binary_userfs_size[]; extern uchar _binary_init_start[], _binary_init_size[]; +void main00(); + // CPU 0 starts running C code here. // This is called main0 not main so that it can have // a void return type. Gcc can't handle functions named @@ -59,18 +60,18 @@ main0(void) fd_init(); iinit(); - // fix process 0 so that copyproc() will work + // initialize process 0 p = &proc[0]; - p->state = IDLEPROC; + p->state = RUNNABLE; p->sz = 4 * PAGE; p->mem = kalloc(p->sz); memset(p->mem, 0, p->sz); p->kstack = kalloc(KSTACKSIZE); - p->tf = (struct trapframe *) (p->kstack + KSTACKSIZE) - 1; - memset(p->tf, 0, sizeof(struct trapframe)); - p->tf->es = p->tf->ds = p->tf->ss = (SEG_UDATA << 3) | 3; - p->tf->cs = (SEG_UCODE << 3) | 3; - p->tf->eflags = FL_IF; + + // cause proc[0] to start in kernel at main00 + memset(&p->jmpbuf, 0, sizeof p->jmpbuf); + p->jmpbuf.eip = (uint)main00; + p->jmpbuf.esp = (uint) (p->kstack + KSTACKSIZE - 4); // make sure there's a TSS setupsegs(0); @@ -89,15 +90,6 @@ main0(void) cpus[cpu()].nlock--; sti(); - // p->cwd = iget(rootdev, 1); - // iunlock(p->cwd); - p = copyproc(&proc[0]); - - //load_icode(p, _binary_usertests_start, (uint) _binary_usertests_size); - //load_icode(p, _binary_userfs_start, (uint) _binary_userfs_size); - load_icode(p, _binary_init_start, (uint) _binary_init_size); - p->state = RUNNABLE; - scheduler(); } @@ -128,6 +120,40 @@ mpmain(void) scheduler(); } +// proc[0] starts here, called by scheduler() in the ordinary way. +void +main00() +{ + struct proc *p0 = &proc[0]; + struct proc *p1; + extern struct spinlock proc_table_lock; + struct trapframe tf; + + release(&proc_table_lock); + + p0->cwd = iget(rootdev, 1); + iunlock(p0->cwd); + + // 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 = &proc[0]; + p0->tf = &tf; + memset(p0->tf, 0, sizeof(struct trapframe)); + p0->tf->es = p0->tf->ds = p0->tf->ss = (SEG_UDATA << 3) | 3; + p0->tf->cs = (SEG_UCODE << 3) | 3; + p0->tf->eflags = FL_IF; + p0->tf->esp = p0->sz; + + p1 = copyproc(&proc[0]); + + load_icode(p1, _binary_init_start, (uint) _binary_init_size); + p1->state = RUNNABLE; + + proc_wait(); + panic("init exited"); +} + void load_icode(struct proc *p, uchar *binary, uint size) { @@ -141,7 +167,6 @@ load_icode(struct proc *p, uchar *binary, uint size) panic("load_icode: not an ELF binary"); p->tf->eip = elf->entry; - p->tf->esp = p->sz; // Map and load segments as directed. ph = (struct proghdr*) (binary + elf->phoff); diff --git a/proc.h b/proc.h index 611f9b5..64e979a 100644 --- a/proc.h +++ b/proc.h @@ -33,8 +33,7 @@ struct jmpbuf { int eip; }; -enum proc_state { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE, - IDLEPROC }; +enum proc_state { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE }; struct proc{ char *mem; // start of process's physical memory diff --git a/trap.c b/trap.c index 2bb3e9e..9d1482f 100644 --- a/trap.c +++ b/trap.c @@ -126,6 +126,8 @@ trap(struct trapframe *tf) } cprintf("trap %d from cpu %d eip %x\n", v, cpu(), tf->eip); + if(curproc[cpu()]) + cprintf("pid %d\n", curproc[cpu()]->pid); panic("trap"); return;