proc[0] can sleep(), at least after it gets to main00()

proc[0] calls iget(rootdev, 1) before forking init
This commit is contained in:
rtm 2006-08-16 01:56:00 +00:00
parent 350e63f7a9
commit ceb0e42796
4 changed files with 48 additions and 22 deletions

View file

@ -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

61
main.c
View file

@ -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);

3
proc.h
View file

@ -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

2
trap.c
View file

@ -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;