diff options
author | rtm <rtm> | 2006-08-29 19:06:37 +0000 |
---|---|---|
committer | rtm <rtm> | 2006-08-29 19:06:37 +0000 |
commit | dfcc5b997ce9c313b9ac0e7d8da39c4416b472a8 (patch) | |
tree | 2d6c4e47bad6cfe7436896068a5872ace545a974 | |
parent | d7ce6545e7179e9a4b950838c354b485e3f3fdb8 (diff) | |
download | xv6-labs-dfcc5b997ce9c313b9ac0e7d8da39c4416b472a8.tar.gz xv6-labs-dfcc5b997ce9c313b9ac0e7d8da39c4416b472a8.tar.bz2 xv6-labs-dfcc5b997ce9c313b9ac0e7d8da39c4416b472a8.zip |
prune unneeded panics and debug output
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | asm.h | 5 | ||||
-rw-r--r-- | bootasm.S | 4 | ||||
-rw-r--r-- | elf.h | 5 | ||||
-rw-r--r-- | init.c | 17 | ||||
-rw-r--r-- | lapic.c | 7 | ||||
-rw-r--r-- | main.c | 45 | ||||
-rw-r--r-- | mmu.h | 73 | ||||
-rw-r--r-- | mp.c | 11 | ||||
-rw-r--r-- | proc.c | 29 | ||||
-rw-r--r-- | proc.h | 4 | ||||
-rw-r--r-- | spinlock.c | 2 | ||||
-rw-r--r-- | syscall.c | 2 | ||||
-rw-r--r-- | trapasm.S | 2 | ||||
-rw-r--r-- | usertests.c | 48 |
15 files changed, 84 insertions, 172 deletions
@@ -70,7 +70,7 @@ PRINT = \ string.c\ print: $(PRINT) -// ~/src/lgrind/source/lgrind -d ~/src/lgrind/lgrindef $(PRINT) > xv6.tex + //~/src/lgrind/source/lgrind -d ~/src/lgrind/lgrindef $(PRINT) > xv6.tex lgrind $(PRINT) > xv6.tex latex xv6.tex dvips -o xv61.ps xv6.dvi @@ -1,3 +1,8 @@ +// +// macros to create x86 segments from assembler +// from JOS +// + #define SEG_NULL \ .word 0, 0; \ .byte 0, 0, 0, 0 @@ -1,3 +1,7 @@ +# +# from JOS +# + #include "asm.h" .set PROT_MODE_CSEG,0x8 # code segment selector @@ -1,3 +1,8 @@ +// +// format of an ELF executable file +// from JOS +// + #define ELF_MAGIC 0x464C457FU /* "\x7FELF" in little endian */ struct elfhdr { @@ -13,20 +13,25 @@ main(void) { int pid; - if(open("console", 0) < 0){ + if(open("console", O_RDWR) < 0){ mknod("console", T_DEV, 1, 1); - open("console", 0); + open("console", O_RDWR); } - open("console", 1); - open("console", 1); + dup(0); + dup(0); while(1){ pid = fork(); + if(pid < 0){ + puts("init: fork failed\n"); + exit(); + } if(pid == 0){ exec("sh", sh_args); + puts("init: exec sh failed\n"); exit(); - } - if(pid > 0) + } else { wait(); + } } } @@ -110,7 +110,6 @@ lapic_write(int r, int data) void lapic_timerinit(void) { - cprintf("cpu%d: init timer\n", cpu()); lapic_write(LAPIC_TDCR, LAPIC_X1); lapic_write(LAPIC_TIMER, LAPIC_CLKIN | LAPIC_PERIODIC | (IRQ_OFFSET + IRQ_TIMER)); lapic_write(LAPIC_TCCR, 10000000); @@ -129,8 +128,6 @@ lapic_init(int c) { uint r, lvt; - cprintf("cpu%d: lapic_init %d\n", c); - lapic_write(LAPIC_DFR, 0xFFFFFFFF); // set destination format register r = (lapic_read(LAPIC_ID)>>24) & 0xFF; // read APIC ID lapic_write(LAPIC_LDR, (1<<r)<<24); // set logical destination register to r @@ -157,8 +154,6 @@ lapic_init(int c) lapic_write(LAPIC_ICRLO, LAPIC_ALLINC|APIC_LEVEL|LAPIC_DEASSERT|APIC_INIT); while(lapic_read(LAPIC_ICRLO) & APIC_DELIVS) ; - - cprintf("cpu%d: apic init done\n", cpu()); } void @@ -204,7 +199,7 @@ lapic_startap(uchar apicid, int v) // in p9 code, this was i < 2, which is what the spec says on page B-3 for(i = 0; i < 1; i++){ lapic_write(LAPIC_ICRHI, crhi); - lapic_write(LAPIC_ICRLO, LAPIC_FIELD|APIC_EDGE|APIC_STARTUP|(v/PGSIZE)); + lapic_write(LAPIC_ICRLO, LAPIC_FIELD|APIC_EDGE|APIC_STARTUP|(v/4096)); while (j++ < 100000) {;} } } @@ -13,7 +13,7 @@ extern char edata[], end[]; extern uchar _binary_init_start[], _binary_init_size[]; -void main00(); +void process0(); // CPU 0 starts running C code here. // This is called main0 not main so that it can have @@ -32,43 +32,33 @@ main0(void) asm volatile("movl %0, %%esp" : : "r" (cpus[0].mpstack + MPSTACK - 32)); asm volatile("movl %0, %%ebp" : : "r" (cpus[0].mpstack + MPSTACK)); - // Make sure interrupts stay disabled on all processors - // until each signals it is ready, by pretending to hold - // an extra lock. - // xxx maybe replace w/ acquire remembering if FL_IF was already clear - for(i=0; i<NCPU; i++){ - cpus[i].nlock++; - cpus[i].guard1 = 0xdeadbeef; - cpus[i].guard2 = 0xdeadbeef; - } + // Prevent release() from enabling interrupts. + for(i=0; i<NCPU; i++) + cpus[i].nlock = 1; mp_init(); // collect info about this machine lapic_init(mp_bcpu()); - cprintf("\n\ncpu%d: booting xv6\n\n", cpu()); + cprintf("\ncpu%d: starting xv6\n\n", cpu()); - pinit(); - binit(); - pic_init(); // initialize PIC + pinit(); // process table + binit(); // buffer cache + pic_init(); ioapic_init(); kinit(); // physical memory allocator tvinit(); // trap vectors - idtinit(); // this CPU's idt register + idtinit(); // this CPU's interrupt descriptor table fd_init(); - iinit(); + iinit(); // i-node table // initialize process 0 p = &proc[0]; p->state = RUNNABLE; - p->sz = 4 * PAGE; - p->mem = kalloc(p->sz); - memset(p->mem, 0, p->sz); p->kstack = kalloc(KSTACKSIZE); - // cause proc[0] to start in kernel at main00 - memset(&p->jmpbuf, 0, sizeof p->jmpbuf); - p->jmpbuf.eip = (uint)main00; + // cause proc[0] to start in kernel at process0 + p->jmpbuf.eip = (uint) process0; p->jmpbuf.esp = (uint) (p->kstack + KSTACKSIZE - 4); // make sure there's a TSS @@ -78,6 +68,7 @@ main0(void) console_init(); ide_init(); + // start other CPUs mp_startthem(); // turn on timer and enable interrupts on the local APIC @@ -118,7 +109,7 @@ mpmain(void) // proc[0] starts here, called by scheduler() in the ordinary way. void -main00() +process0() { struct proc *p0 = &proc[0]; struct proc *p1; @@ -130,10 +121,13 @@ main00() p0->cwd = iget(rootdev, 1); iunlock(p0->cwd); + // dummy user memory to make copyproc() happy + p0->sz = 4 * PAGE; + p0->mem = kalloc(p0->sz); + // 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; @@ -141,7 +135,7 @@ main00() p0->tf->eflags = FL_IF; p0->tf->esp = p0->sz; - p1 = copyproc(&proc[0]); + p1 = copyproc(p0); load_icode(p1, _binary_init_start, (uint) _binary_init_size); p1->state = RUNNABLE; @@ -157,7 +151,6 @@ load_icode(struct proc *p, uchar *binary, uint size) struct elfhdr *elf; struct proghdr *ph; - // Check magic number on binary elf = (struct elfhdr*) binary; if (elf->magic != ELF_MAGIC) panic("load_icode: not an ELF binary"); @@ -1,15 +1,8 @@ /* - * This file contains definitions for the x86 memory management unit (MMU), - * including paging- and segmentation-related data structures and constants, - * the %cr0, %cr4, and %eflags registers, and traps. + * This file contains definitions for the x86 memory management unit (MMU). + * from JOS. */ -/* - * Register flags and fundamental constants. - */ - -#define PGSIZE 4096 // bytes mapped by a page - // Eflags register #define FL_CF 0x00000001 // Carry Flag #define FL_PF 0x00000004 // Parity Flag @@ -33,33 +26,7 @@ #define FL_VIP 0x00100000 // Virtual Interrupt Pending #define FL_ID 0x00200000 // ID flag -// Page fault error codes -#define FEC_PR 0x1 // Page fault caused by protection violation -#define FEC_WR 0x2 // Page fault caused by a write -#define FEC_U 0x4 // Page fault occured while in user mode - -/* - * - * Segmentation data structures and constants. - * - */ - -#ifdef __ASSEMBLER__ - -/* - * Macros to build GDT entries in assembly. - */ -#define SEG_NULL \ - .word 0, 0; \ - .byte 0, 0, 0, 0 -#define SEG(type,base,lim) \ - .word (((lim) >> 12) & 0xffff), ((base) & 0xffff); \ - .byte (((base) >> 16) & 0xff), (0x90 | (type)), \ - (0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff) - -#else // not __ASSEMBLER__ - -// Segment Descriptors +// Segment Descriptor struct segdesc { uint lim_15_0 : 16; // Low bits of segment limit uint base_15_0 : 16; // Low bits of segment base address @@ -75,22 +42,21 @@ struct segdesc { uint g : 1; // Granularity: limit scaled by 4K when set uint base_31_24 : 8; // High bits of segment base address }; + // Null segment #define SEG_NULL (struct segdesc){ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } -// Segment that is loadable but faults when used -#define SEG_FAULT (struct segdesc){ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 } + // Normal segment #define SEG(type, base, lim, dpl) (struct segdesc) \ { ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff, \ type, 1, dpl, 1, (uint) (lim) >> 28, 0, 0, 1, 1, \ (uint) (base) >> 24 } + #define SEG16(type, base, lim, dpl) (struct segdesc) \ { (lim) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff, \ type, 1, dpl, 1, (uint) (lim) >> 16, 0, 0, 1, 0, \ (uint) (base) >> 24 } -#endif /* !__ASSEMBLER__ */ - // Application segment type bits #define STA_X 0x8 // Executable segment #define STA_E 0x4 // Expand down (non-executable segments) @@ -113,16 +79,7 @@ struct segdesc { #define STS_IG32 0xE // 32-bit Interrupt Gate #define STS_TG32 0xF // 32-bit Trap Gate - -/* - * - * Traps. - * - */ - -#ifndef __ASSEMBLER__ - -// Task state segment format (as described by the Pentium architecture book) +// Task state segment format struct taskstate { uint link; // Old ts selector uint esp0; // Stack pointers and segment selectors @@ -197,19 +154,3 @@ struct gatedesc { (gate).off_31_16 = (uint) (off) >> 16; \ } -// Set up a call gate descriptor. -#define SETCALLGATE(gate, ss, off, d) \ -{ \ - (gate).off_15_0 = (uint) (off) & 0xffff; \ - (gate).ss = (ss); \ - (gate).args = 0; \ - (gate).rsv1 = 0; \ - (gate).type = STS_CG32; \ - (gate).s = 0; \ - (gate).dpl = (d); \ - (gate).p = 1; \ - (gate).off_31_16 = (uint) (off) >> 16; \ -} - -#endif /* !__ASSEMBLER__ */ - @@ -42,7 +42,6 @@ mp_scan(uchar *addr, int len) uchar *e, *p, sum; int i; - cprintf("scanning: 0x%x\n", (uint)addr); e = addr+len; for(p = addr; p < e; p += sizeof(struct mp)){ if(memcmp(p, "_MP_", 4)) @@ -131,8 +130,6 @@ mp_init(void) ncpu = 0; if ((r = mp_detect()) != 0) return; - cprintf("Mp spec rev #: %x imcrp 0x%x\n", mp->specrev, mp->imcrp); - /* * Run through the table saving information needed for starting * application processors and initialising any I/O APICs. The table @@ -140,7 +137,6 @@ mp_init(void) */ mpctb = (struct mpctb *) mp->physaddr; lapicaddr = (uint *) mpctb->lapicaddr; - cprintf("apicaddr: %x\n", lapicaddr); p = ((uchar*)mpctb)+sizeof(struct mpctb); e = ((uchar*)mpctb)+mpctb->length; @@ -149,7 +145,6 @@ mp_init(void) case MPPROCESSOR: proc = (struct mppe *) p; cpus[ncpu].apicid = proc->apicid; - cprintf("a processor %x\n", cpus[ncpu].apicid); if (proc->flags & MPBP) { bcpu = &cpus[ncpu]; } @@ -162,18 +157,15 @@ mp_init(void) if(strncmp(buses[i], bus->string, sizeof(bus->string)) == 0) break; } - cprintf("a bus %d\n", i); p += sizeof(struct mpbe); continue; case MPIOAPIC: ioapic = (struct mpioapic *) p; - cprintf("an I/O APIC: id %d %x\n", ioapic->apicno, ioapic->flags); ioapic_id = ioapic->apicno; p += sizeof(struct mpioapic); continue; case MPIOINTR: intr = (struct mpie *) p; - // cprintf("an I/O intr: type %d flags 0x%x bus %d souce bus irq %d dest ioapic id %d dest ioapic intin %d\n", intr->intr, intr->flags, intr->busno, intr->irq, intr->apicno, intr->intin); p += sizeof(struct mpie); continue; default: @@ -192,8 +184,6 @@ mp_init(void) byte |= 0x01; /* mask external INTR */ outb(0x23, byte); /* disconnect 8259s/NMI */ } - - cprintf("ncpu: %d boot %d\n", ncpu, bcpu-cpus); } @@ -219,7 +209,6 @@ mp_startthem(void) for(c = 0; c < ncpu; c++){ if (c == cpu()) continue; - cprintf ("cpu%d: starting processor %d\n", cpu(), c); *(uint *)(APBOOTCODE-4) = (uint) (cpus[c].mpstack) + MPSTACK; // tell it what to use for %esp *(uint *)(APBOOTCODE-8) = (uint)mpmain; // tell it where to jump to lapic_startap(cpus[c].apicid, (uint) APBOOTCODE); @@ -169,18 +169,11 @@ scheduler(void) struct proc *p; int i; - if(cpus[cpu()].nlock != 0){ - cprintf("la %x lr %x\n", cpus[cpu()].lastacquire, cpus[cpu()].lastrelease ); - panic("holding locks at first entry to scheduler"); - } - for(;;){ // Loop over process table looking for process to run. acquire(&proc_table_lock); + for(i = 0; i < NPROC; i++){ - if(cpus[cpu()].guard1 != 0xdeadbeef || - cpus[cpu()].guard2 != 0xdeadbeef) - panic("cpu guard"); p = &proc[i]; if(p->state != RUNNABLE) continue; @@ -198,31 +191,11 @@ scheduler(void) // Process is done running for now. // It should have changed its p->state before coming back. curproc[cpu()] = 0; - if(p->state == RUNNING) - panic("swtch to scheduler with state=RUNNING"); - if(!holding(&proc_table_lock)){ - cprintf("back to scheduler without proc_table_lock (pid=%d state=%d)", p->pid, p->state); - panic("scheduler lock"); - } - if(cpus[cpu()].nlock != 1){ - cprintf("holding %d locks in scheduler (pid=%d state=%d)\n", cpus[cpu()].nlock, p->pid, p->state); - panic("scheduler lock"); - } - setupsegs(0); } release(&proc_table_lock); - - if(cpus[cpu()].nlock != 0) - panic("holding locks in scheduler"); - - // With proc_table_lock released, there are no - // locks held on this cpu, so interrupts are enabled. - // Hardware interrupts can happen here. - // Also, releasing the lock here lets the other CPUs - // look for runnable processes too. } } @@ -66,13 +66,9 @@ struct cpu { struct jmpbuf jmpbuf; struct taskstate ts; // only to give cpu address of kernel stack struct segdesc gdt[NSEGS]; - int guard1; char mpstack[MPSTACK]; // per-cpu start-up stack - int guard2; volatile int booted; int nlock; // # of locks currently held - struct spinlock *lastacquire; // xxx debug - struct spinlock *lastrelease; // xxx debug }; extern struct cpu cpus[NCPU]; @@ -43,7 +43,6 @@ acquire(struct spinlock * lock) cpuid(0, 0, 0, 0, 0); // memory barrier getcallerpcs(&lock, lock->pcs); lock->cpu = cpu() + 10; - cpus[cpu()].lastacquire = lock; } void @@ -53,7 +52,6 @@ release(struct spinlock * lock) if(!holding(lock)) panic("release"); - cpus[cpu()].lastrelease = lock; lock->pcs[0] = 0; lock->cpu = 0xffffffff; cpuid(0, 0, 0, 0, 0); // memory barrier @@ -473,7 +473,7 @@ sys_getpid(void) int sys_sbrk(void) { - unsigned addr; + uint addr; int n; struct proc *cp = curproc[cpu()]; @@ -1,5 +1,3 @@ -#include "mmu.h" - .text .globl trap .globl trapret1 diff --git a/usertests.c b/usertests.c index badaa1c..54cebbd 100644 --- a/usertests.c +++ b/usertests.c @@ -13,7 +13,10 @@ pipe1(void) int fds[2], pid; int seq = 0, i, n, cc, total; - pipe(fds); + if(pipe(fds) != 0){ + puts("pipe() failed\n"); + exit(); + } pid = fork(); if(pid == 0){ close(fds[0]); @@ -26,7 +29,7 @@ pipe1(void) } } exit(); - } else { + } else if(pid > 0){ close(fds[1]); total = 0; cc = 1; @@ -43,9 +46,12 @@ pipe1(void) cc = sizeof(buf); } if(total != 5 * 1033) - printf(1, "pipe1 oops 3\n"); + printf(1, "pipe1 oops 3 total %d\n", total); close(fds[0]); wait(); + } else { + puts("fork() failed\n"); + exit(); } puts("pipe1 ok\n"); } @@ -121,26 +127,30 @@ void mem(void) { void *m1, *m2; + int pid; - m1 = 0; - while ((m2 = malloc(1024)) != 0) { - printf(1, "malloc %x\n", m2); - *(char **) m2 = m1; - m1 = m2; - } - while (m1) { - m2 = *(char **)m1; + if((pid = fork()) == 0){ + m1 = 0; + while ((m2 = malloc(10001)) != 0) { + *(char **) m2 = m1; + m1 = m2; + } + while (m1) { + m2 = *(char **)m1; + free(m1); + m1 = m2; + } + m1 = malloc(1024*20); + if (m1 == 0) { + puts("couldn't allocate mem?!!\n"); + exit(); + } free(m1); - m1 = m2; - } - m1 = malloc(1024*20); - if (m1 == 0) { - puts("couldn't allocate mem?!!\n"); + printf(1, "mem ok\n"); exit(); + } else { + wait(); } - free(m1); - - printf(1, "mem ok\n"); } int |