From ceb0e427962d0656e672955585c04093b9efda90 Mon Sep 17 00:00:00 2001
From: rtm <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;
-- 
GitLab