compile "user programs"
curproc array
This commit is contained in:
parent
bf49aedbed
commit
df5cc91659
11 changed files with 139 additions and 64 deletions
10
Makefile
10
Makefile
|
@ -20,18 +20,22 @@ bootblock : bootasm.S bootmain.c
|
||||||
$(OBJCOPY) -S -O binary bootblock.o bootblock
|
$(OBJCOPY) -S -O binary bootblock.o bootblock
|
||||||
./sign.pl bootblock
|
./sign.pl bootblock
|
||||||
|
|
||||||
kernel : $(OBJS) bootother.S
|
kernel : $(OBJS) bootother.S user1
|
||||||
$(CC) -nostdinc -I. -c bootother.S
|
$(CC) -nostdinc -I. -c bootother.S
|
||||||
$(LD) -N -e start -Ttext 0x7000 -o bootother.out bootother.o
|
$(LD) -N -e start -Ttext 0x7000 -o bootother.out bootother.o
|
||||||
$(OBJCOPY) -S -O binary bootother.out bootother
|
$(OBJCOPY) -S -O binary bootother.out bootother
|
||||||
$(OBJDUMP) -S bootother.o > bootother.asm
|
$(OBJDUMP) -S bootother.o > bootother.asm
|
||||||
$(LD) -Ttext 0x100000 -e main -o kernel $(OBJS) -b binary bootother
|
$(LD) -Ttext 0x100000 -e main -o kernel $(OBJS) -b binary bootother user1
|
||||||
$(OBJDUMP) -S kernel > kernel.asm
|
$(OBJDUMP) -S kernel > kernel.asm
|
||||||
|
|
||||||
vectors.S : vectors.pl
|
vectors.S : vectors.pl
|
||||||
perl vectors.pl > vectors.S
|
perl vectors.pl > vectors.S
|
||||||
|
|
||||||
|
user1 : user1.c
|
||||||
|
$(CC) -nostdinc -I. -c user1.c
|
||||||
|
$(LD) -N -e main -Ttext 0 -o user1 user1.o
|
||||||
|
|
||||||
-include *.d
|
-include *.d
|
||||||
|
|
||||||
clean :
|
clean :
|
||||||
rm -f *.o bootblock kernel kernel.asm xv6.img *.d
|
rm -f *.o bootblock kernel kernel.asm xv6.img *.d user1
|
||||||
|
|
4
defs.h
4
defs.h
|
@ -33,7 +33,7 @@ void pic_init(void);
|
||||||
|
|
||||||
// mp.c
|
// mp.c
|
||||||
void mp_init(void);
|
void mp_init(void);
|
||||||
int lapic_cpu_number(void);
|
int cpu(void);
|
||||||
int mp_isbcpu(void);
|
int mp_isbcpu(void);
|
||||||
|
|
||||||
// spinlock.c
|
// spinlock.c
|
||||||
|
@ -42,3 +42,5 @@ void acquire_spinlock(uint32_t* lock);
|
||||||
void release_spinlock(uint32_t* lock);
|
void release_spinlock(uint32_t* lock);
|
||||||
void release_grant_spinlock(uint32_t* lock, int cpu);
|
void release_grant_spinlock(uint32_t* lock, int cpu);
|
||||||
|
|
||||||
|
// main.c
|
||||||
|
void load_icode(struct proc *p, uint8_t *binary, unsigned size);
|
||||||
|
|
54
main.c
54
main.c
|
@ -6,9 +6,13 @@
|
||||||
#include "x86.h"
|
#include "x86.h"
|
||||||
#include "traps.h"
|
#include "traps.h"
|
||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
|
#include "elf.h"
|
||||||
|
#include "param.h"
|
||||||
|
|
||||||
extern char edata[], end[];
|
extern char edata[], end[];
|
||||||
extern int acpu;
|
extern int acpu;
|
||||||
|
extern char _binary_user1_start[];
|
||||||
|
extern char _binary_user1_size[];
|
||||||
|
|
||||||
char buf[512];
|
char buf[512];
|
||||||
|
|
||||||
|
@ -16,12 +20,14 @@ int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (acpu) {
|
if (acpu) {
|
||||||
cprintf("an application processor\n");
|
cprintf("an application processor\n");
|
||||||
release_spinlock(&kernel_lock);
|
release_spinlock(&kernel_lock);
|
||||||
while (1) ;
|
acquire_spinlock(&kernel_lock);
|
||||||
|
lapic_init(cpu());
|
||||||
|
curproc[cpu()] = &proc[0]; // XXX
|
||||||
|
swtch();
|
||||||
}
|
}
|
||||||
acpu = 1;
|
acpu = 1;
|
||||||
// clear BSS
|
// clear BSS
|
||||||
|
@ -34,11 +40,9 @@ main()
|
||||||
tinit(); // traps and interrupts
|
tinit(); // traps and interrupts
|
||||||
pic_init();
|
pic_init();
|
||||||
|
|
||||||
while (1);
|
|
||||||
|
|
||||||
// create fake process zero
|
// create fake process zero
|
||||||
p = &proc[0];
|
p = &proc[0];
|
||||||
curproc = p;
|
curproc[cpu()] = p;
|
||||||
p->state = WAITING;
|
p->state = WAITING;
|
||||||
p->sz = PAGE;
|
p->sz = PAGE;
|
||||||
p->mem = kalloc(p->sz);
|
p->mem = kalloc(p->sz);
|
||||||
|
@ -54,17 +58,20 @@ main()
|
||||||
setupsegs(p);
|
setupsegs(p);
|
||||||
|
|
||||||
// turn on interrupts
|
// turn on interrupts
|
||||||
|
irq_setmask_8259A(0xff);
|
||||||
write_eflags(read_eflags() | FL_IF);
|
write_eflags(read_eflags() | FL_IF);
|
||||||
irq_setmask_8259A(0);
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
ide_read(0, buf, 1);
|
ide_read(0, buf, 1);
|
||||||
cprintf("sec0.0 %x\n", buf[0] & 0xff);
|
cprintf("sec0.0 %x\n", buf[0] & 0xff);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
p = newproc();
|
p = newproc();
|
||||||
|
load_icode(p, _binary_user1_start, (unsigned) _binary_user1_size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
i = 0;
|
i = 0;
|
||||||
p->mem[i++] = 0x90; // nop
|
p->mem[i++] = 0x90; // nop
|
||||||
p->mem[i++] = 0xb8; // mov ..., %eax
|
p->mem[i++] = 0xb8; // mov ..., %eax
|
||||||
|
@ -96,3 +103,36 @@ main()
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
load_icode(struct proc *p, uint8_t *binary, unsigned size)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct Elf *elf;
|
||||||
|
struct Proghdr *ph;
|
||||||
|
|
||||||
|
// Check magic number on binary
|
||||||
|
elf = (struct Elf*) binary;
|
||||||
|
cprintf("elf %x magic %x\n", elf, elf->e_magic);
|
||||||
|
if (elf->e_magic != ELF_MAGIC)
|
||||||
|
panic("load_icode: not an ELF binary");
|
||||||
|
|
||||||
|
p->tf->tf_eip = elf->e_entry;
|
||||||
|
p->tf->tf_esp = p->sz;
|
||||||
|
|
||||||
|
// Map and load segments as directed.
|
||||||
|
ph = (struct Proghdr*) (binary + elf->e_phoff);
|
||||||
|
for (i = 0; i < elf->e_phnum; i++, ph++) {
|
||||||
|
if (ph->p_type != ELF_PROG_LOAD)
|
||||||
|
continue;
|
||||||
|
cprintf("va %x memsz %d\n", ph->p_va, ph->p_memsz);
|
||||||
|
if (ph->p_va + ph->p_memsz < ph->p_va)
|
||||||
|
panic("load_icode: overflow in elf header segment");
|
||||||
|
if (ph->p_va + ph->p_memsz >= p->sz)
|
||||||
|
panic("load_icode: icode wants to be above UTOP");
|
||||||
|
|
||||||
|
// Load/clear the segment
|
||||||
|
memcpy(p->mem + ph->p_va, binary + ph->p_offset, ph->p_filesz);
|
||||||
|
memset(p->mem + ph->p_va + ph->p_filesz, 0, ph->p_memsz - ph->p_filesz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
32
mp.c
32
mp.c
|
@ -97,7 +97,7 @@ static uint32_t *lapicaddr;
|
||||||
static struct cpu {
|
static struct cpu {
|
||||||
uint8_t apicid; /* Local APIC ID */
|
uint8_t apicid; /* Local APIC ID */
|
||||||
int lintr[2]; /* Local APIC */
|
int lintr[2]; /* Local APIC */
|
||||||
} cpu[NCPU];
|
} cpus[NCPU];
|
||||||
static int ncpu;
|
static int ncpu;
|
||||||
static struct cpu *bcpu;
|
static struct cpu *bcpu;
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ lapic_write(int r, int data)
|
||||||
*(lapicaddr+(r/sizeof(*lapicaddr))) = data;
|
*(lapicaddr+(r/sizeof(*lapicaddr))) = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
lapic_init(int c)
|
lapic_init(int c)
|
||||||
{
|
{
|
||||||
uint32_t r, lvt;
|
uint32_t r, lvt;
|
||||||
|
@ -131,8 +131,8 @@ lapic_init(int c)
|
||||||
* LINT[01] are set to ExtINT.
|
* LINT[01] are set to ExtINT.
|
||||||
* Acknowledge any outstanding interrupts.
|
* Acknowledge any outstanding interrupts.
|
||||||
*/
|
*/
|
||||||
lapic_write(LAPIC_LINT0, cpu[c].lintr[0]);
|
lapic_write(LAPIC_LINT0, cpus[c].lintr[0]);
|
||||||
lapic_write(LAPIC_LINT1, cpu[c].lintr[1]);
|
lapic_write(LAPIC_LINT1, cpus[c].lintr[1]);
|
||||||
lapic_write(LAPIC_EOI, 0);
|
lapic_write(LAPIC_EOI, 0);
|
||||||
|
|
||||||
lvt = (lapic_read(LAPIC_VER)>>16) & 0xFF;
|
lvt = (lapic_read(LAPIC_VER)>>16) & 0xFF;
|
||||||
|
@ -168,7 +168,7 @@ lapic_online(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
lapic_cpu_number(void)
|
cpu(void)
|
||||||
{
|
{
|
||||||
return (lapic_read(LAPIC_ID)>>24) & 0xFF;
|
return (lapic_read(LAPIC_ID)>>24) & 0xFF;
|
||||||
}
|
}
|
||||||
|
@ -312,12 +312,12 @@ mp_init()
|
||||||
switch(*p){
|
switch(*p){
|
||||||
case MPPROCESSOR:
|
case MPPROCESSOR:
|
||||||
proc = (struct MPPE *) p;
|
proc = (struct MPPE *) p;
|
||||||
cpu[ncpu].apicid = proc->apicid;
|
cpus[ncpu].apicid = proc->apicid;
|
||||||
cpu[ncpu].lintr[0] = APIC_IMASK;
|
cpus[ncpu].lintr[0] = APIC_IMASK;
|
||||||
cpu[ncpu].lintr[1] = APIC_IMASK;
|
cpus[ncpu].lintr[1] = APIC_IMASK;
|
||||||
cprintf("a processor %x\n", cpu[ncpu].apicid);
|
cprintf("a processor %x\n", cpus[ncpu].apicid);
|
||||||
if (proc->flags & MPBP) {
|
if (proc->flags & MPBP) {
|
||||||
bcpu = &cpu[ncpu];
|
bcpu = &cpus[ncpu];
|
||||||
}
|
}
|
||||||
ncpu++;
|
ncpu++;
|
||||||
p += sizeof(struct MPPE);
|
p += sizeof(struct MPPE);
|
||||||
|
@ -342,8 +342,8 @@ mp_init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lapic_init(cpu-bcpu);
|
lapic_init(bcpu-cpus);
|
||||||
cprintf("ncpu: %d boot %d\n", ncpu, cpu-bcpu);
|
cprintf("ncpu: %d boot %d\n", ncpu, bcpu-cpus);
|
||||||
|
|
||||||
lapic_online();
|
lapic_online();
|
||||||
|
|
||||||
|
@ -352,12 +352,12 @@ mp_init()
|
||||||
(uint32_t) _binary_bootother_size);
|
(uint32_t) _binary_bootother_size);
|
||||||
|
|
||||||
acquire_spinlock(&kernel_lock);
|
acquire_spinlock(&kernel_lock);
|
||||||
for (c = cpu; c < &cpu[ncpu]; c++) {
|
for (c = cpus; c < &cpus[ncpu]; c++) {
|
||||||
if (c == bcpu) continue;
|
if (c == bcpu) continue;
|
||||||
cprintf ("starting processor %d\n", c - cpu);
|
cprintf ("starting processor %d\n", c - cpus);
|
||||||
release_grant_spinlock(&kernel_lock, c - cpu);
|
release_grant_spinlock(&kernel_lock, c - cpus);
|
||||||
lapic_startap(c, (uint32_t) KADDR(APBOOTCODE));
|
lapic_startap(c, (uint32_t) KADDR(APBOOTCODE));
|
||||||
acquire_spinlock(&kernel_lock);
|
acquire_spinlock(&kernel_lock);
|
||||||
cprintf ("done starting processor %d\n", c - cpu);
|
cprintf ("done starting processor %d\n", c - cpus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
46
proc.c
46
proc.c
|
@ -1,12 +1,12 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "mmu.h"
|
#include "mmu.h"
|
||||||
#include "x86.h"
|
#include "x86.h"
|
||||||
#include "proc.h"
|
|
||||||
#include "param.h"
|
#include "param.h"
|
||||||
|
#include "proc.h"
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
struct proc proc[NPROC];
|
struct proc proc[NPROC];
|
||||||
struct proc *curproc;
|
struct proc *curproc[NCPU];
|
||||||
int next_pid = 1;
|
int next_pid = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -47,6 +47,7 @@ struct proc *
|
||||||
newproc()
|
newproc()
|
||||||
{
|
{
|
||||||
struct proc *np;
|
struct proc *np;
|
||||||
|
struct proc *op = curproc[cpu()];
|
||||||
unsigned *sp;
|
unsigned *sp;
|
||||||
|
|
||||||
for(np = &proc[1]; np < &proc[NPROC]; np++)
|
for(np = &proc[1]; np < &proc[NPROC]; np++)
|
||||||
|
@ -56,22 +57,22 @@ newproc()
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
np->pid = next_pid++;
|
np->pid = next_pid++;
|
||||||
np->ppid = curproc->pid;
|
np->ppid = op->pid;
|
||||||
np->sz = curproc->sz;
|
np->sz = op->sz;
|
||||||
np->mem = kalloc(curproc->sz);
|
np->mem = kalloc(op->sz);
|
||||||
if(np->mem == 0)
|
if(np->mem == 0)
|
||||||
return 0;
|
return 0;
|
||||||
memcpy(np->mem, curproc->mem, np->sz);
|
memcpy(np->mem, op->mem, np->sz);
|
||||||
np->kstack = kalloc(KSTACKSIZE);
|
np->kstack = kalloc(KSTACKSIZE);
|
||||||
if(np->kstack == 0){
|
if(np->kstack == 0){
|
||||||
kfree(np->mem, curproc->sz);
|
kfree(np->mem, op->sz);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
setupsegs(np);
|
setupsegs(np);
|
||||||
|
|
||||||
// set up kernel stack to return to user space
|
// set up kernel stack to return to user space
|
||||||
np->tf = (struct Trapframe *) (np->kstack + KSTACKSIZE - sizeof(struct Trapframe));
|
np->tf = (struct Trapframe *) (np->kstack + KSTACKSIZE - sizeof(struct Trapframe));
|
||||||
*(np->tf) = *(curproc->tf);
|
*(np->tf) = *(op->tf);
|
||||||
sp = (unsigned *) np->tf;
|
sp = (unsigned *) np->tf;
|
||||||
*(--sp) = (unsigned) &trapret; // for return from swtch()
|
*(--sp) = (unsigned) &trapret; // for return from swtch()
|
||||||
*(--sp) = 0; // previous bp for leave in swtch()
|
*(--sp) = 0; // previous bp for leave in swtch()
|
||||||
|
@ -92,31 +93,38 @@ void
|
||||||
swtch()
|
swtch()
|
||||||
{
|
{
|
||||||
struct proc *np;
|
struct proc *np;
|
||||||
|
struct proc *op = curproc[cpu()];
|
||||||
|
|
||||||
|
cprintf("swtch cpu %d op %x proc0 %x\n", cpu(), op, proc);
|
||||||
while(1){
|
while(1){
|
||||||
for(np = curproc + 1; np != curproc; np++){
|
np = op + 1;
|
||||||
if(np == &proc[NPROC])
|
while(np != op){
|
||||||
np = &proc[0];
|
|
||||||
if(np->state == RUNNABLE)
|
if(np->state == RUNNABLE)
|
||||||
break;
|
break;
|
||||||
|
np++;
|
||||||
|
if(np == &proc[NPROC])
|
||||||
|
np = &proc[0];
|
||||||
}
|
}
|
||||||
if(np->state == RUNNABLE)
|
if(np->state == RUNNABLE)
|
||||||
break;
|
break;
|
||||||
// idle...
|
cprintf("swtch: nothing to run\n");
|
||||||
|
release_spinlock(&kernel_lock);
|
||||||
|
acquire_spinlock(&kernel_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
curproc->ebp = read_ebp();
|
op->ebp = read_ebp();
|
||||||
curproc->esp = read_esp();
|
op->esp = read_esp();
|
||||||
|
|
||||||
cprintf("swtch %x -> %x\n", curproc, np);
|
cprintf("cpu %d swtch %x -> %x\n", cpu(), op, np);
|
||||||
|
|
||||||
curproc = np;
|
curproc[cpu()] = np;
|
||||||
|
np->state = RUNNING;
|
||||||
|
|
||||||
// XXX callee-saved registers?
|
// XXX callee-saved registers?
|
||||||
|
|
||||||
// h/w sets busy bit in TSS descriptor sometimes, and faults
|
// h/w sets busy bit in TSS descriptor sometimes, and faults
|
||||||
// if it's set in LTR. so clear tss descriptor busy bit.
|
// if it's set in LTR. so clear tss descriptor busy bit.
|
||||||
curproc->gdt[SEG_TSS].sd_type = STS_T32A;
|
np->gdt[SEG_TSS].sd_type = STS_T32A;
|
||||||
|
|
||||||
// XXX probably ought to lgdt on trap return too, in case
|
// XXX probably ought to lgdt on trap return too, in case
|
||||||
// a system call has moved a program or changed its size.
|
// a system call has moved a program or changed its size.
|
||||||
|
@ -134,8 +142,8 @@ swtch()
|
||||||
void
|
void
|
||||||
sleep(void *chan)
|
sleep(void *chan)
|
||||||
{
|
{
|
||||||
curproc->chan = chan;
|
curproc[cpu()]->chan = chan;
|
||||||
curproc->state = WAITING;
|
curproc[cpu()]->state = WAITING;
|
||||||
swtch();
|
swtch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
proc.h
4
proc.h
|
@ -20,7 +20,7 @@ struct proc{
|
||||||
char *mem; // start of process's physical memory
|
char *mem; // start of process's physical memory
|
||||||
unsigned sz; // total size of mem, including kernel stack
|
unsigned sz; // total size of mem, including kernel stack
|
||||||
char *kstack; // kernel stack, separate from mem so it doesn't move
|
char *kstack; // kernel stack, separate from mem so it doesn't move
|
||||||
enum { UNUSED, RUNNABLE, WAITING, ZOMBIE } state;
|
enum { UNUSED, RUNNABLE, WAITING, ZOMBIE, RUNNING } state;
|
||||||
int pid;
|
int pid;
|
||||||
int ppid;
|
int ppid;
|
||||||
void *chan; // sleep
|
void *chan; // sleep
|
||||||
|
@ -35,4 +35,4 @@ struct proc{
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct proc proc[];
|
extern struct proc proc[];
|
||||||
extern struct proc *curproc;
|
extern struct proc *curproc[NCPU];
|
||||||
|
|
|
@ -10,18 +10,18 @@ uint32_t kernel_lock = LOCK_FREE;
|
||||||
void
|
void
|
||||||
acquire_spinlock(uint32_t* lock)
|
acquire_spinlock(uint32_t* lock)
|
||||||
{
|
{
|
||||||
int cpu_id = lapic_cpu_number();
|
int cpu_id = cpu();
|
||||||
cprintf ("acquire: %d\n", cpu_id);
|
|
||||||
|
|
||||||
if (*lock == cpu_id)
|
if (*lock == cpu_id)
|
||||||
return;
|
return;
|
||||||
while ( cmpxchg(LOCK_FREE, cpu_id, lock) != cpu_id ) { ; }
|
while ( cmpxchg(LOCK_FREE, cpu_id, lock) != cpu_id ) { ; }
|
||||||
|
cprintf ("acquired: %d\n", cpu_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
release_spinlock(uint32_t* lock)
|
release_spinlock(uint32_t* lock)
|
||||||
{
|
{
|
||||||
int cpu_id = lapic_cpu_number();
|
int cpu_id = cpu();
|
||||||
cprintf ("release: %d\n", cpu_id);
|
cprintf ("release: %d\n", cpu_id);
|
||||||
if (*lock != cpu_id)
|
if (*lock != cpu_id)
|
||||||
panic("release_spinlock: releasing a lock that i don't own\n");
|
panic("release_spinlock: releasing a lock that i don't own\n");
|
||||||
|
@ -31,7 +31,7 @@ release_spinlock(uint32_t* lock)
|
||||||
void
|
void
|
||||||
release_grant_spinlock(uint32_t* lock, int c)
|
release_grant_spinlock(uint32_t* lock, int c)
|
||||||
{
|
{
|
||||||
int cpu_id = lapic_cpu_number();
|
int cpu_id = cpu();
|
||||||
cprintf ("release_grant: %d -> %d\n", cpu_id, c);
|
cprintf ("release_grant: %d -> %d\n", cpu_id, c);
|
||||||
if (*lock != cpu_id)
|
if (*lock != cpu_id)
|
||||||
panic("release_spinlock: releasing a lock that i don't own\n");
|
panic("release_spinlock: releasing a lock that i don't own\n");
|
||||||
|
|
25
syscall.c
25
syscall.c
|
@ -25,17 +25,18 @@ void
|
||||||
sys_exit()
|
sys_exit()
|
||||||
{
|
{
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
|
struct proc *cp = curproc[cpu()];
|
||||||
|
|
||||||
curproc->state = ZOMBIE;
|
cp->state = ZOMBIE;
|
||||||
|
|
||||||
// wake up parent
|
// wake up parent
|
||||||
for(p = proc; p < &proc[NPROC]; p++)
|
for(p = proc; p < &proc[NPROC]; p++)
|
||||||
if(p->pid == curproc->ppid)
|
if(p->pid == cp->ppid)
|
||||||
wakeup(p);
|
wakeup(p);
|
||||||
|
|
||||||
// abandon children
|
// abandon children
|
||||||
for(p = proc; p < &proc[NPROC]; p++)
|
for(p = proc; p < &proc[NPROC]; p++)
|
||||||
if(p->ppid == curproc->pid)
|
if(p->ppid == cp->pid)
|
||||||
p->pid = 1;
|
p->pid = 1;
|
||||||
|
|
||||||
swtch();
|
swtch();
|
||||||
|
@ -45,37 +46,39 @@ void
|
||||||
sys_wait()
|
sys_wait()
|
||||||
{
|
{
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
|
struct proc *cp = curproc[cpu()];
|
||||||
int any;
|
int any;
|
||||||
|
|
||||||
cprintf("waid pid %d ppid %d\n", curproc->pid, curproc->ppid);
|
cprintf("waid pid %d ppid %d\n", cp->pid, cp->ppid);
|
||||||
|
|
||||||
while(1){
|
while(1){
|
||||||
any = 0;
|
any = 0;
|
||||||
for(p = proc; p < &proc[NPROC]; p++){
|
for(p = proc; p < &proc[NPROC]; p++){
|
||||||
if(p->state == ZOMBIE && p->ppid == curproc->pid){
|
if(p->state == ZOMBIE && p->ppid == cp->pid){
|
||||||
kfree(p->mem, p->sz);
|
kfree(p->mem, p->sz);
|
||||||
kfree(p->kstack, KSTACKSIZE);
|
kfree(p->kstack, KSTACKSIZE);
|
||||||
p->state = UNUSED;
|
p->state = UNUSED;
|
||||||
cprintf("%x collected %x\n", curproc, p);
|
cprintf("%x collected %x\n", cp, p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(p->state != UNUSED && p->ppid == curproc->pid)
|
if(p->state != UNUSED && p->ppid == cp->pid)
|
||||||
any = 1;
|
any = 1;
|
||||||
}
|
}
|
||||||
if(any == 0){
|
if(any == 0){
|
||||||
cprintf("%x nothing to wait for\n", curproc);
|
cprintf("%x nothing to wait for\n", cp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sleep(curproc);
|
sleep(cp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
syscall()
|
syscall()
|
||||||
{
|
{
|
||||||
int num = curproc->tf->tf_regs.reg_eax;
|
struct proc *cp = curproc[cpu()];
|
||||||
|
int num = cp->tf->tf_regs.reg_eax;
|
||||||
|
|
||||||
cprintf("%x sys %d\n", curproc, num);
|
cprintf("%x sys %d\n", cp, num);
|
||||||
switch(num){
|
switch(num){
|
||||||
case SYS_fork:
|
case SYS_fork:
|
||||||
sys_fork();
|
sys_fork();
|
||||||
|
|
5
trap.c
5
trap.c
|
@ -29,10 +29,13 @@ void
|
||||||
trap(struct Trapframe *tf)
|
trap(struct Trapframe *tf)
|
||||||
{
|
{
|
||||||
int v = tf->tf_trapno;
|
int v = tf->tf_trapno;
|
||||||
|
|
||||||
|
acquire_spinlock(&kernel_lock); // released in trapret in trapasm.S
|
||||||
|
|
||||||
cprintf("trap %d eip %x:%x\n", tf->tf_trapno, tf->tf_cs, tf->tf_eip);
|
cprintf("trap %d eip %x:%x\n", tf->tf_trapno, tf->tf_cs, tf->tf_eip);
|
||||||
|
|
||||||
if(v == T_SYSCALL){
|
if(v == T_SYSCALL){
|
||||||
curproc->tf = tf;
|
curproc[cpu()]->tf = tf;
|
||||||
syscall();
|
syscall();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@ alltraps:
|
||||||
* expects ESP to point to a Trapframe
|
* expects ESP to point to a Trapframe
|
||||||
*/
|
*/
|
||||||
trapret:
|
trapret:
|
||||||
|
push $kernel_lock
|
||||||
|
call release_spinlock
|
||||||
popal
|
popal
|
||||||
popl %es
|
popl %es
|
||||||
popl %ds
|
popl %ds
|
||||||
|
|
13
user1.c
Normal file
13
user1.c
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
void
|
||||||
|
fork()
|
||||||
|
{
|
||||||
|
asm("mov $1, %eax");
|
||||||
|
asm("int $48");
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
fork();
|
||||||
|
while(1)
|
||||||
|
;
|
||||||
|
}
|
Loading…
Reference in a new issue