diff --git a/defs.h b/defs.h index 387341b..f10859e 100644 --- a/defs.h +++ b/defs.h @@ -17,7 +17,8 @@ void sleep(void *); void wakeup(void *); // trap.c -void tinit(void); +void tvinit(void); +void idtinit(void); // string.c void * memcpy(void *dst, void *src, unsigned n); diff --git a/main.c b/main.c index 206daf3..1226a8f 100644 --- a/main.c +++ b/main.c @@ -25,6 +25,7 @@ main() cprintf("an application processor\n"); release_spinlock(&kernel_lock); acquire_spinlock(&kernel_lock); + idtinit(); lapic_init(cpu()); curproc[cpu()] = &proc[0]; // XXX swtch(); @@ -37,7 +38,8 @@ main() mp_init(); // multiprocessor kinit(); // physical memory allocator - tinit(); // traps and interrupts + tvinit(); // trap vectors + idtinit(); // CPU's idt pic_init(); // create fake process zero diff --git a/proc.c b/proc.c index 9247cc7..e8a911d 100644 --- a/proc.c +++ b/proc.c @@ -73,6 +73,7 @@ newproc() // set up kernel stack to return to user space np->tf = (struct Trapframe *) (np->kstack + KSTACKSIZE - sizeof(struct Trapframe)); *(np->tf) = *(op->tf); + np->tf->tf_regs.reg_eax = 0; // so fork() returns 0 in child sp = (unsigned *) np->tf; *(--sp) = (unsigned) &trapret; // for return from swtch() *(--sp) = 0; // previous bp for leave in swtch() diff --git a/syscall.c b/syscall.c index beadcbb..1d2eb54 100644 --- a/syscall.c +++ b/syscall.c @@ -42,13 +42,16 @@ fetcharg(int argno, int *ip) return fetchint(curproc[cpu()], esp + 8 + 4*argno, ip); } -void +int sys_fork() { - newproc(); + struct proc *np; + + np = newproc(); + return np->pid; } -void +int sys_exit() { struct proc *p; @@ -67,14 +70,16 @@ sys_exit() p->pid = 1; swtch(); + + return 0; } -void +int sys_wait() { struct proc *p; struct proc *cp = curproc[cpu()]; - int any; + int any, pid; cprintf("waid pid %d ppid %d\n", cp->pid, cp->ppid); @@ -84,28 +89,30 @@ sys_wait() if(p->state == ZOMBIE && p->ppid == cp->pid){ kfree(p->mem, p->sz); kfree(p->kstack, KSTACKSIZE); + pid = p->pid; p->state = UNUSED; cprintf("%x collected %x\n", cp, p); - return; + return pid; } if(p->state != UNUSED && p->ppid == cp->pid) any = 1; } if(any == 0){ cprintf("%x nothing to wait for\n", cp); - return; + return -1; } sleep(cp); } } -void +int sys_cons_putc() { int c; fetcharg(0, &c); cons_putc(c & 0xff); + return 0; } void @@ -113,24 +120,26 @@ syscall() { struct proc *cp = curproc[cpu()]; int num = cp->tf->tf_regs.reg_eax; + int ret = -1; cprintf("%x sys %d\n", cp, num); switch(num){ case SYS_fork: - sys_fork(); + ret = sys_fork(); break; case SYS_exit: - sys_exit(); + ret = sys_exit(); break; case SYS_wait: - sys_wait(); + ret = sys_wait(); break; case SYS_cons_putc: - sys_cons_putc(); + ret = sys_cons_putc(); break; default: cprintf("unknown sys call %d\n", num); // XXX fault break; } + cp->tf->tf_regs.reg_eax = ret; } diff --git a/trap.c b/trap.c index 33d7be1..0cd4958 100644 --- a/trap.c +++ b/trap.c @@ -14,7 +14,7 @@ extern void trapenter(); extern void trapenter1(); void -tinit() +tvinit() { int i; @@ -22,6 +22,11 @@ tinit() SETGATE(idt[i], 1, SEG_KCODE << 3, vectors[i], 0); } SETGATE(idt[T_SYSCALL], T_SYSCALL, SEG_KCODE << 3, vectors[48], 3); +} + +void +idtinit() +{ asm volatile("lidt %0" : : "g" (idt_pd.pd_lim)); } diff --git a/user1.c b/user1.c index ea260a2..9e0c731 100644 --- a/user1.c +++ b/user1.c @@ -1,4 +1,4 @@ -void +int fork() { asm("mov $1, %eax"); @@ -12,19 +12,25 @@ cons_putc(int c) asm("int $48"); } -void +int puts(char *s) { int i; for(i = 0; s[i]; i++) cons_putc(s[i]); + return i; } main() { - // fork(); - puts("hello!\n"); + int pid; + pid = fork(); + if(pid == 0){ + cons_putc('C'); + } else { + cons_putc('P'); + } while(1) ; }