summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--defs.h3
-rw-r--r--main.c4
-rw-r--r--proc.c1
-rw-r--r--syscall.c33
-rw-r--r--trap.c7
-rw-r--r--user1.c14
6 files changed, 43 insertions, 19 deletions
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)
;
}