diff options
| author | rtm <rtm> | 2006-06-22 20:47:23 +0000 | 
|---|---|---|
| committer | rtm <rtm> | 2006-06-22 20:47:23 +0000 | 
| commit | df5cc91659b0a2190072e6fc305060c8de95ed82 (patch) | |
| tree | 0965b8a673f0e2ddab08b2135ab1499f6455c648 | |
| parent | bf49aedbed02cdbf40430178847d34c48c36c693 (diff) | |
| download | xv6-labs-df5cc91659b0a2190072e6fc305060c8de95ed82.tar.gz xv6-labs-df5cc91659b0a2190072e6fc305060c8de95ed82.tar.bz2 xv6-labs-df5cc91659b0a2190072e6fc305060c8de95ed82.zip | |
compile "user programs"
curproc array
| -rw-r--r-- | Makefile | 10 | ||||
| -rw-r--r-- | defs.h | 4 | ||||
| -rw-r--r-- | main.c | 54 | ||||
| -rw-r--r-- | mp.c | 32 | ||||
| -rw-r--r-- | proc.c | 46 | ||||
| -rw-r--r-- | proc.h | 4 | ||||
| -rw-r--r-- | spinlock.c | 8 | ||||
| -rw-r--r-- | syscall.c | 25 | ||||
| -rw-r--r-- | trap.c | 5 | ||||
| -rw-r--r-- | trapasm.S | 2 | ||||
| -rw-r--r-- | user1.c | 13 | 
11 files changed, 139 insertions, 64 deletions
| @@ -20,18 +20,22 @@ bootblock : bootasm.S bootmain.c  	$(OBJCOPY) -S -O binary bootblock.o bootblock  	./sign.pl bootblock -kernel : $(OBJS) bootother.S +kernel : $(OBJS) bootother.S user1  	$(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 main -o kernel $(OBJS) -b binary bootother +	$(LD) -Ttext 0x100000 -e main -o kernel $(OBJS) -b binary bootother user1  	$(OBJDUMP) -S kernel > kernel.asm  vectors.S : vectors.pl  	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  clean :  -	rm -f *.o bootblock kernel kernel.asm xv6.img *.d +	rm -f *.o bootblock kernel kernel.asm xv6.img *.d user1 @@ -33,7 +33,7 @@ void pic_init(void);  // mp.c  void mp_init(void); -int lapic_cpu_number(void); +int cpu(void);  int mp_isbcpu(void);  // spinlock.c @@ -42,3 +42,5 @@ void acquire_spinlock(uint32_t* lock);  void release_spinlock(uint32_t* lock);  void release_grant_spinlock(uint32_t* lock, int cpu); +// main.c +void load_icode(struct proc *p, uint8_t *binary, unsigned size); @@ -6,9 +6,13 @@  #include "x86.h"  #include "traps.h"  #include "syscall.h" +#include "elf.h" +#include "param.h"  extern char edata[], end[];  extern int acpu; +extern char _binary_user1_start[]; +extern char _binary_user1_size[];  char buf[512]; @@ -16,12 +20,14 @@ int  main()  {    struct proc *p; -  int i;    if (acpu) {      cprintf("an application processor\n");      release_spinlock(&kernel_lock); -    while (1) ; +    acquire_spinlock(&kernel_lock); +    lapic_init(cpu()); +    curproc[cpu()] = &proc[0]; // XXX +    swtch();    }    acpu = 1;    // clear BSS @@ -34,11 +40,9 @@ main()    tinit(); // traps and interrupts    pic_init(); -  while (1); -    // create fake process zero    p = &proc[0]; -  curproc = p; +  curproc[cpu()] = p;    p->state = WAITING;    p->sz = PAGE;    p->mem = kalloc(p->sz); @@ -54,17 +58,20 @@ main()    setupsegs(p);    // turn on interrupts +  irq_setmask_8259A(0xff);    write_eflags(read_eflags() | FL_IF); -  irq_setmask_8259A(0);  #if 0    ide_read(0, buf, 1);    cprintf("sec0.0 %x\n", buf[0] & 0xff);  #endif -#if 0 +#if 1    p = newproc(); +  load_icode(p, _binary_user1_start, (unsigned) _binary_user1_size); +#endif +#if 0    i = 0;    p->mem[i++] = 0x90; // nop     p->mem[i++] = 0xb8; // mov ..., %eax @@ -96,3 +103,36 @@ main()    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); +	} +} @@ -97,7 +97,7 @@ static uint32_t *lapicaddr;  static struct cpu {    uint8_t apicid;       /* Local APIC ID */    int lintr[2];		/* Local APIC */ -} cpu[NCPU]; +} cpus[NCPU];  static int ncpu;  static struct cpu *bcpu; @@ -113,7 +113,7 @@ lapic_write(int r, int data)    *(lapicaddr+(r/sizeof(*lapicaddr))) = data;  } -static void +void  lapic_init(int c)  {    uint32_t r, lvt; @@ -131,8 +131,8 @@ lapic_init(int c)     * LINT[01] are set to ExtINT.     * Acknowledge any outstanding interrupts.     */ -  lapic_write(LAPIC_LINT0, cpu[c].lintr[0]); -  lapic_write(LAPIC_LINT1, cpu[c].lintr[1]); +  lapic_write(LAPIC_LINT0, cpus[c].lintr[0]); +  lapic_write(LAPIC_LINT1, cpus[c].lintr[1]);    lapic_write(LAPIC_EOI, 0);    lvt = (lapic_read(LAPIC_VER)>>16) & 0xFF; @@ -168,7 +168,7 @@ lapic_online(void)  }  int -lapic_cpu_number(void) +cpu(void)  {    return (lapic_read(LAPIC_ID)>>24) & 0xFF;  } @@ -312,12 +312,12 @@ mp_init()      switch(*p){      case MPPROCESSOR:        proc = (struct MPPE *) p; -      cpu[ncpu].apicid = proc->apicid; -      cpu[ncpu].lintr[0] = APIC_IMASK; -      cpu[ncpu].lintr[1] = APIC_IMASK; -      cprintf("a processor %x\n", cpu[ncpu].apicid); +      cpus[ncpu].apicid = proc->apicid; +      cpus[ncpu].lintr[0] = APIC_IMASK; +      cpus[ncpu].lintr[1] = APIC_IMASK; +      cprintf("a processor %x\n", cpus[ncpu].apicid);        if (proc->flags & MPBP) { -	bcpu = &cpu[ncpu]; +	bcpu = &cpus[ncpu];        }        ncpu++;        p += sizeof(struct MPPE); @@ -342,8 +342,8 @@ mp_init()      }    } -  lapic_init(cpu-bcpu); -  cprintf("ncpu: %d boot %d\n", ncpu, cpu-bcpu); +  lapic_init(bcpu-cpus); +  cprintf("ncpu: %d boot %d\n", ncpu, bcpu-cpus);    lapic_online(); @@ -352,12 +352,12 @@ mp_init()  	  (uint32_t) _binary_bootother_size);    acquire_spinlock(&kernel_lock); -  for (c = cpu; c < &cpu[ncpu]; c++) { +  for (c = cpus; c < &cpus[ncpu]; c++) {      if (c == bcpu) continue; -    cprintf ("starting processor %d\n", c - cpu); -    release_grant_spinlock(&kernel_lock, c - cpu); +    cprintf ("starting processor %d\n", c - cpus); +    release_grant_spinlock(&kernel_lock, c - cpus);      lapic_startap(c, (uint32_t) KADDR(APBOOTCODE));      acquire_spinlock(&kernel_lock); -    cprintf ("done starting processor %d\n", c - cpu); +    cprintf ("done starting processor %d\n", c - cpus);    }  } @@ -1,12 +1,12 @@  #include "types.h"  #include "mmu.h"  #include "x86.h" -#include "proc.h"  #include "param.h" +#include "proc.h"  #include "defs.h"  struct proc proc[NPROC]; -struct proc *curproc; +struct proc *curproc[NCPU];  int next_pid = 1;  /* @@ -47,6 +47,7 @@ struct proc *  newproc()  {    struct proc *np; +  struct proc *op = curproc[cpu()];    unsigned *sp;    for(np = &proc[1]; np < &proc[NPROC]; np++) @@ -56,22 +57,22 @@ newproc()      return 0;    np->pid = next_pid++; -  np->ppid = curproc->pid; -  np->sz = curproc->sz; -  np->mem = kalloc(curproc->sz); +  np->ppid = op->pid; +  np->sz = op->sz; +  np->mem = kalloc(op->sz);    if(np->mem == 0)      return 0; -  memcpy(np->mem, curproc->mem, np->sz); +  memcpy(np->mem, op->mem, np->sz);    np->kstack = kalloc(KSTACKSIZE);    if(np->kstack == 0){ -    kfree(np->mem, curproc->sz); +    kfree(np->mem, op->sz);      return 0;    }    setupsegs(np);    // set up kernel stack to return to user space    np->tf = (struct Trapframe *) (np->kstack + KSTACKSIZE - sizeof(struct Trapframe)); -  *(np->tf) = *(curproc->tf); +  *(np->tf) = *(op->tf);    sp = (unsigned *) np->tf;    *(--sp) = (unsigned) &trapret;  // for return from swtch()    *(--sp) = 0;  // previous bp for leave in swtch() @@ -92,31 +93,38 @@ void  swtch()  {    struct proc *np; +  struct proc *op = curproc[cpu()]; +  cprintf("swtch cpu %d op %x proc0 %x\n", cpu(), op, proc);    while(1){ -    for(np = curproc + 1; np != curproc; np++){ -      if(np == &proc[NPROC]) -        np = &proc[0]; +    np = op + 1; +    while(np != op){        if(np->state == RUNNABLE)          break; +      np++; +      if(np == &proc[NPROC]) +        np = &proc[0];      }      if(np->state == RUNNABLE)        break; -    // idle... +    cprintf("swtch: nothing to run\n"); +    release_spinlock(&kernel_lock); +    acquire_spinlock(&kernel_lock);    } -  curproc->ebp = read_ebp(); -  curproc->esp = read_esp(); +  op->ebp = read_ebp(); +  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?    // h/w sets busy bit in TSS descriptor sometimes, and faults    // 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    // a system call has moved a program or changed its size. @@ -134,8 +142,8 @@ swtch()  void  sleep(void *chan)  { -  curproc->chan = chan; -  curproc->state = WAITING; +  curproc[cpu()]->chan = chan; +  curproc[cpu()]->state = WAITING;    swtch();  } @@ -20,7 +20,7 @@ struct proc{    char *mem; // start of process's physical memory    unsigned sz; // total size of mem, including kernel stack    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 ppid;    void *chan; // sleep @@ -35,4 +35,4 @@ struct 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   acquire_spinlock(uint32_t* lock)  { -  int cpu_id = lapic_cpu_number(); -  cprintf ("acquire: %d\n", cpu_id); +  int cpu_id = cpu();    if (*lock == cpu_id)      return;    while ( cmpxchg(LOCK_FREE, cpu_id, lock) != cpu_id ) { ; } +  cprintf ("acquired: %d\n", cpu_id);  }  void  release_spinlock(uint32_t* lock)  { -  int cpu_id = lapic_cpu_number(); +  int cpu_id = cpu();    cprintf ("release: %d\n", cpu_id);    if (*lock != cpu_id)      panic("release_spinlock: releasing a lock that i don't own\n"); @@ -31,7 +31,7 @@ release_spinlock(uint32_t* lock)  void  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);    if (*lock != cpu_id)      panic("release_spinlock: releasing a lock that i don't own\n"); @@ -25,17 +25,18 @@ void  sys_exit()  {    struct proc *p; +  struct proc *cp = curproc[cpu()]; -  curproc->state = ZOMBIE; +  cp->state = ZOMBIE;    // wake up parent    for(p = proc; p < &proc[NPROC]; p++) -    if(p->pid == curproc->ppid) +    if(p->pid == cp->ppid)        wakeup(p);    // abandon children    for(p = proc; p < &proc[NPROC]; p++) -    if(p->ppid == curproc->pid) +    if(p->ppid == cp->pid)        p->pid = 1;    swtch(); @@ -45,37 +46,39 @@ void  sys_wait()  {    struct proc *p; +  struct proc *cp = curproc[cpu()];    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){      any = 0;      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->kstack, KSTACKSIZE);          p->state = UNUSED; -        cprintf("%x collected %x\n", curproc, p); +        cprintf("%x collected %x\n", cp, p);          return;        } -      if(p->state != UNUSED && p->ppid == curproc->pid) +      if(p->state != UNUSED && p->ppid == cp->pid)          any = 1;      }      if(any == 0){ -      cprintf("%x nothing to wait for\n", curproc); +      cprintf("%x nothing to wait for\n", cp);        return;      } -    sleep(curproc); +    sleep(cp);    }  }  void  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){    case SYS_fork:      sys_fork(); @@ -29,10 +29,13 @@ void  trap(struct Trapframe *tf)  {    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);    if(v == T_SYSCALL){ -    curproc->tf = tf; +    curproc[cpu()]->tf = tf;      syscall();      return;    } @@ -22,6 +22,8 @@ alltraps:           * expects ESP to point to a Trapframe           */  trapret: +        push $kernel_lock +        call release_spinlock          popal          popl %es          popl %ds @@ -0,0 +1,13 @@ +void +fork() +{ +  asm("mov $1, %eax"); +  asm("int $48"); +} + +main() +{ +  fork(); +  while(1) +    ; +} | 
