diff options
| -rw-r--r-- | Notes | 44 | ||||
| -rw-r--r-- | console.c | 8 | ||||
| -rw-r--r-- | defs.h | 2 | ||||
| -rw-r--r-- | main.c | 4 | ||||
| -rw-r--r-- | param.h | 20 | ||||
| -rw-r--r-- | proc.c | 8 | ||||
| -rw-r--r-- | spinlock.c | 43 | ||||
| -rw-r--r-- | spinlock.h | 1 | ||||
| -rw-r--r-- | syscall.c | 6 | ||||
| -rw-r--r-- | trap.c | 45 | ||||
| -rw-r--r-- | x86.h | 212 | 
11 files changed, 46 insertions, 347 deletions
| @@ -95,49 +95,15 @@ inode->count counts in-memory pointers to the struct  blocks and inodes have ad-hoc sleep-locks    provide a single mechanism? -test 14-character file names -and file arguments longer than 14 -  kalloc() can return 0; do callers handle this right? -OH! recursive interrupts will use up any amount of cpu[].stack! -  underflow and wrecks *previous* cpu's struct - -disk scheduling -mkdir -sh arguments -sh redirection -indirect blocks -is there a create/create race for same file name? -  resulting in two entries w/ same name in directory? -why does shell often ignore first line of input? -  test: one process unlinks a file while another links to it  test: one process opens a file while another deletes it -test: mkdir. deadlock d/.. vs ../d, two processes. +test: deadlock d/.. vs ../d, two processes.  test: dup() shared fd->off  test: sbrk  test: does echo foo > x truncate x? -make proc[0] runnable -cpu early tss and gdt -how do we get cpu0 scheduler() to use mpstack, not proc[0].kstack? -when iget() first sleeps, where does it longjmp to? -maybe set up proc[0] to be runnable, with entry proc0main(), then -  have main() call scheduler()? -  perhaps so proc[0] uses right kstack? -  and scheduler() uses mpstack? -ltr sets the busy bit in the TSS, faults if already set -  so gdt and TSS per cpu? -  we don't want to be using some random process's gdt when it changes it. -maybe get rid of per-proc gdt and ts -  one per cpu -  refresh it when needed -  setupsegs(proc *) - -why do we get 0 characters from keyboard? -are the locks in the right place in keyboardintr? -  sh: support pipes?  leave it for the class?  sh: dynamic memory allocation?  sh: should sh support ; () &  --- need malloc @@ -146,3 +112,11 @@ sh: stop stdin on ctrl-d (for cat > y)  really should have bdwrite() for file content    and make some inode updates async    so soft updates make sense + +disk scheduling +echo foo > bar should truncate bar +  so O_CREATE should not truncate +  but O_TRUNC should + +make it work on one cpu +make it work on amsterdam @@ -9,10 +9,6 @@ struct spinlock console_lock;  int panicked = 0;  int use_console_lock = 0; -// per-cpu copy of output to help panic/lock debugging -char obuf[NCPU][1024]; -uint obufi[NCPU]; -  /*   * copy console output to parallel port, which you can tell   * .bochsrc to copy to the stdout: @@ -37,10 +33,6 @@ cons_putc(int c)    ushort *crt = (ushort *) 0xB8000; // base of CGA memory    int ind; -  obuf[rcr4()][obufi[rcr4()]++] = c; -  if(obufi[rcr4()] >= 1024) -    obufi[rcr4()] = 0; -    if(panicked){      cli();      for(;;) @@ -16,7 +16,7 @@ struct jmpbuf;  void setupsegs(struct proc *);  struct proc * copyproc(struct proc*);  struct spinlock; -char *growproc(int); +int growproc(int);  void sleep(void *, struct spinlock *);  void wakeup(void *);  void scheduler(void); @@ -25,8 +25,6 @@ main0(void)    int i;    struct proc *p; -  lcr4(0); // xxx copy of cpu # -    // clear BSS    memset(edata, 0, end - edata); @@ -97,8 +95,6 @@ main0(void)  void  mpmain(void)  { -  lcr4(1); // xxx copy of cpu # -    cprintf("cpu%d: starting\n", cpu());    idtinit(); // CPU's idt    if(cpu() == 0) @@ -1,10 +1,10 @@ -#define NPROC 64 -#define PAGE 4096 -#define KSTACKSIZE PAGE -#define NCPU 8 -#define NOFILE 16 // file descriptors per process -#define NFD 100 // file descriptors per system -#define NREQUEST 100 // outstanding disk requests -#define NBUF 10 -#define NINODE 100 -#define NDEV 10 +#define NPROC 64        // maximum number of processes +#define PAGE 4096       // granularity of user-space memory allocation +#define KSTACKSIZE PAGE // size of per-process kernel stack +#define NCPU 8          // maximum number of CPUs +#define NOFILE 16       // file descriptors per process +#define NFD 100         // file descriptors per system +#define NREQUEST 100    // outstanding disk requests +#define NBUF 10         // size of disk block cache +#define NINODE 100      // maximum number of active i-nodes +#define NDEV 10         // maximum major device number @@ -138,22 +138,22 @@ copyproc(struct proc* p)    return np;  } -char * +int  growproc(int n)  {    struct proc *cp = curproc[cpu()];    char *newmem, *oldmem;    newmem = kalloc(cp->sz + n); -  if(newmem == 0) return (char *) -1; +  if(newmem == 0) +    return -1;    memmove(newmem, cp->mem, cp->sz);    memset(newmem + cp->sz, 0, n);    oldmem = cp->mem;    cp->mem = newmem;    kfree(oldmem, cp->sz); -  cprintf("growproc: added %d bytes to %d bytes\n", n, cp->sz);    cp->sz += n; -  return cp->sz - n; +  return 0;  }  // Per-CPU process scheduler.  @@ -6,18 +6,11 @@  #include "proc.h"  #include "spinlock.h" -// Can't call cprintf from inside these routines, -// because cprintf uses them itself. -//#define cprintf dont_use_cprintf - -#define LOCKMAGIC 0x6673ffea -  extern int use_console_lock;  void  initlock(struct spinlock *lock, char *name)  { -  lock->magic = LOCKMAGIC;    lock->name = name;    lock->locked = 0;    lock->cpu = 0xffffffff; @@ -38,8 +31,6 @@ getcallerpcs(void *v, uint pcs[])  void  acquire(struct spinlock * lock)  { -  if(lock->magic != LOCKMAGIC) -    panic("weird lock magic");    if(holding(lock))      panic("acquire"); @@ -47,34 +38,32 @@ acquire(struct spinlock * lock)      cli();    cpus[cpu()].nlock++; -	while(cmpxchg(0, 1, &lock->locked) == 1) -		; -	cpuid(0, 0, 0, 0, 0);	// memory barrier -	getcallerpcs(&lock, lock->pcs); -	lock->cpu = cpu() + 10; -        cpus[cpu()].lastacquire = lock; +  while(cmpxchg(0, 1, &lock->locked) == 1) +    ; +  cpuid(0, 0, 0, 0, 0);	// memory barrier +  getcallerpcs(&lock, lock->pcs); +  lock->cpu = cpu() + 10; +  cpus[cpu()].lastacquire = lock;  }  void  release(struct spinlock * lock)  { -  if(lock->magic != LOCKMAGIC) -    panic("weird lock magic"); -	if(!holding(lock)) -		panic("release"); +  if(!holding(lock)) +    panic("release"); -        cpus[cpu()].lastrelease = lock; -        lock->pcs[0] = 0; -        lock->cpu = 0xffffffff; -	cpuid(0, 0, 0, 0, 0);	// memory barrier -	lock->locked = 0; -	if(--cpus[cpu()].nlock == 0) -		sti(); +  cpus[cpu()].lastrelease = lock; +  lock->pcs[0] = 0; +  lock->cpu = 0xffffffff; +  cpuid(0, 0, 0, 0, 0);	// memory barrier +  lock->locked = 0; +  if(--cpus[cpu()].nlock == 0) +    sti();  }  int  holding(struct spinlock *lock)  { -	return lock->locked && lock->cpu == cpu() + 10; +  return lock->locked && lock->cpu == cpu() + 10;  } @@ -1,5 +1,4 @@  struct spinlock { -  uint magic;    char *name;    uint locked;    int cpu; @@ -473,15 +473,15 @@ sys_getpid(void)  int  sys_sbrk(void)  { -  char *r;    int n;    struct proc *cp = curproc[cpu()];    if(fetcharg(0, &n) < 0)      return -1; -  r = growproc(n); +  if(growproc(n) != 0) +    return -1;    setupsegs(cp);   -  return (int) r; +  return 0;  }  int @@ -34,59 +34,19 @@ void  trap(struct trapframe *tf)  {    int v = tf->trapno; -   -  if(cpus[cpu()].nlock){ -    cprintf("trap v %d eip %x cpu %d nlock %d\n", -            v, tf->eip, cpu(), cpus[cpu()].nlock); -    panic("interrupt while holding a lock"); -  } - -  if(curproc[cpu()] == 0){ -    if(&tf < cpus[cpu()].mpstack || &tf > cpus[cpu()].mpstack + MPSTACK){ -      cprintf("&tf %x mpstack %x\n", &tf, cpus[cpu()].mpstack); -      panic("trap cpu stack"); -    } -  } else if(curproc[cpu()]){ -    if(&tf < curproc[cpu()]->kstack){ -      panic("trap kstack"); -    } -  }    if(v == T_SYSCALL){      struct proc *cp = curproc[cpu()];      int num = cp->tf->eax; -    if((read_eflags() & FL_IF) == 0) -      panic("syscall but interrupts now disabled"); -    if(cp == 0) -      panic("syscall with no proc");      if(cp->killed)        proc_exit();      cp->tf = tf;      syscall(); -    if(cp != curproc[cpu()]) -      panic("trap ret wrong curproc"); -    if(cp->state != RUNNING) -      panic("trap ret but not RUNNING"); -    if(tf != cp->tf) -      panic("trap ret wrong tf"); -    if(cpus[cpu()].nlock){ -      cprintf("num=%d\n", num); -      panic("syscall returning locks held"); -    } -    if((read_eflags() & FL_IF) == 0) -      panic("syscall returning but FL_IF clear"); -    if(read_esp() < (uint)cp->kstack || -       read_esp() >= (uint)cp->kstack + KSTACKSIZE) -      panic("trap ret esp wrong");      if(cp->killed)        proc_exit(); -    // XXX probably ought to lgdt on trap return      return;    } -  //if(read_eflags() & FL_IF) -  //panic("interrupt but interrupts enabled"); -    if(v == (IRQ_OFFSET + IRQ_TIMER)){      struct proc *cp = curproc[cpu()];      lapic_timerintr(); @@ -108,8 +68,6 @@ trap(struct trapframe *tf)    if(v == (IRQ_OFFSET + IRQ_IDE)){      ide_intr(); -    if(cpus[cpu()].nlock) -      panic("ide_intr returned while holding a lock");      cli(); // prevent a waiting interrupt from overflowing stack      lapic_eoi();      return; @@ -117,9 +75,6 @@ trap(struct trapframe *tf)    if(v == (IRQ_OFFSET + IRQ_KBD)){      kbd_intr(); -    if(cpus[cpu()].nlock){ -      panic("kbd_intr returned while holding a lock"); -    }      cli(); // prevent a waiting interrupt from overflowing stack      lapic_eoi();      return; @@ -1,45 +1,3 @@ -static __inline void breakpoint(void) __attribute__((always_inline)); -static __inline uchar inb(int port) __attribute__((always_inline)); -static __inline void insb(int port, void *addr, int cnt) __attribute__((always_inline)); -static __inline ushort inw(int port) __attribute__((always_inline)); -static __inline void insw(int port, void *addr, int cnt) __attribute__((always_inline)); -static __inline uint inl(int port) __attribute__((always_inline)); -static __inline void insl(int port, void *addr, int cnt) __attribute__((always_inline)); -static __inline void outb(int port, uchar data) __attribute__((always_inline)); -static __inline void outsb(int port, const void *addr, int cnt) __attribute__((always_inline)); -static __inline void outw(int port, ushort data) __attribute__((always_inline)); -static __inline void outsw(int port, const void *addr, int cnt) __attribute__((always_inline)); -static __inline void outsl(int port, const void *addr, int cnt) __attribute__((always_inline)); -static __inline void outl(int port, uint data) __attribute__((always_inline)); -static __inline void invlpg(void *addr) __attribute__((always_inline)); -struct segdesc; -static __inline void lgdt(struct segdesc *p, int) __attribute__((always_inline)); -struct gatedesc; -static __inline void lidt(struct gatedesc *p, int) __attribute__((always_inline)); -static __inline void lldt(ushort sel) __attribute__((always_inline)); -static __inline void ltr(ushort sel) __attribute__((always_inline)); -static __inline void lcr0(uint val) __attribute__((always_inline)); -static __inline uint rcr0(void) __attribute__((always_inline)); -static __inline uint rcr2(void) __attribute__((always_inline)); -static __inline void lcr3(uint val) __attribute__((always_inline)); -static __inline uint rcr3(void) __attribute__((always_inline)); -static __inline void lcr4(uint val) __attribute__((always_inline)); -static __inline uint rcr4(void) __attribute__((always_inline)); -static __inline void tlbflush(void) __attribute__((always_inline)); -static __inline uint read_eflags(void) __attribute__((always_inline)); -static __inline void write_eflags(uint eflags) __attribute__((always_inline)); -static __inline uint read_ebp(void) __attribute__((always_inline)); -static __inline uint read_esp(void) __attribute__((always_inline)); -static __inline void cpuid(uint info, uint *eaxp, uint *ebxp, uint *ecxp, uint *edxp); -static __inline void cli(void) __attribute__((always_inline)); -static __inline void sti(void) __attribute__((always_inline)); - -static __inline void -breakpoint(void) -{ -	__asm __volatile("int3"); -} -  static __inline uchar  inb(int port)  { @@ -49,40 +7,6 @@ inb(int port)  }  static __inline void -insb(int port, void *addr, int cnt) -{ -	__asm __volatile("cld\n\trepne\n\tinsb"			: -			 "=D" (addr), "=c" (cnt)		: -			 "d" (port), "0" (addr), "1" (cnt)	: -			 "memory", "cc"); -} - -static __inline ushort -inw(int port) -{ -	ushort data; -	__asm __volatile("inw %w1,%0" : "=a" (data) : "d" (port)); -	return data; -} - -static __inline void -insw(int port, void *addr, int cnt) -{ -	__asm __volatile("cld\n\trepne\n\tinsw"			: -			 "=D" (addr), "=c" (cnt)		: -			 "d" (port), "0" (addr), "1" (cnt)	: -			 "memory", "cc"); -} - -static __inline uint -inl(int port) -{ -	uint data; -	__asm __volatile("inl %w1,%0" : "=a" (data) : "d" (port)); -	return data; -} - -static __inline void  insl(int port, void *addr, int cnt)  {  	__asm __volatile("cld\n\trepne\n\tinsl"			: @@ -98,30 +22,12 @@ outb(int port, uchar data)  }  static __inline void -outsb(int port, const void *addr, int cnt) -{ -	__asm __volatile("cld\n\trepne\n\toutsb"		: -			 "=S" (addr), "=c" (cnt)		: -			 "d" (port), "0" (addr), "1" (cnt)	: -			 "cc"); -} - -static __inline void  outw(int port, ushort data)  {  	__asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));  }  static __inline void -outsw(int port, const void *addr, int cnt) -{ -	__asm __volatile("cld\n\trepne\n\toutsw"		: -			 "=S" (addr), "=c" (cnt)		: -			 "d" (port), "0" (addr), "1" (cnt)	: -			 "cc"); -} - -static __inline void  outsl(int port, const void *addr, int cnt)  {  	__asm __volatile("cld\n\trepne\n\toutsl"		: @@ -130,17 +36,7 @@ outsl(int port, const void *addr, int cnt)  			 "cc");  } -static __inline void -outl(int port, uint data) -{ -	__asm __volatile("outl %0,%w1" : : "a" (data), "d" (port)); -} - -static __inline void  -invlpg(void *addr) -{  -	__asm __volatile("invlpg (%0)" : : "r" (addr) : "memory"); -}   +struct segdesc;  static __inline void  lgdt(struct segdesc *p, int size) @@ -154,6 +50,8 @@ lgdt(struct segdesc *p, int size)  	asm volatile("lgdt (%0)" : : "g" (pd));  } +struct gatedesc; +  static __inline void  lidt(struct gatedesc *p, int size)  { @@ -167,75 +65,11 @@ lidt(struct gatedesc *p, int size)  }  static __inline void -lldt(ushort sel) -{ -	__asm __volatile("lldt %0" : : "r" (sel)); -} - -static __inline void  ltr(ushort sel)  {  	__asm __volatile("ltr %0" : : "r" (sel));  } -static __inline void -lcr0(uint val) -{ -	__asm __volatile("movl %0,%%cr0" : : "r" (val)); -} - -static __inline uint -rcr0(void) -{ -	uint val; -	__asm __volatile("movl %%cr0,%0" : "=r" (val)); -	return val; -} - -static __inline uint -rcr2(void) -{ -	uint val; -	__asm __volatile("movl %%cr2,%0" : "=r" (val)); -	return val; -} - -static __inline void -lcr3(uint val) -{ -	__asm __volatile("movl %0,%%cr3" : : "r" (val)); -} - -static __inline uint -rcr3(void) -{ -	uint val; -	__asm __volatile("movl %%cr3,%0" : "=r" (val)); -	return val; -} - -static __inline void -lcr4(uint val) -{ -	__asm __volatile("movl %0,%%cr4" : : "r" (val)); -} - -static __inline uint -rcr4(void) -{ -	uint cr4; -	__asm __volatile("movl %%cr4,%0" : "=r" (cr4)); -	return cr4; -} - -static __inline void -tlbflush(void) -{ -	uint cr3; -	__asm __volatile("movl %%cr3,%0" : "=r" (cr3)); -	__asm __volatile("movl %0,%%cr3" : : "r" (cr3)); -} -  static __inline uint  read_eflags(void)  { @@ -250,46 +84,6 @@ write_eflags(uint eflags)          __asm __volatile("pushl %0; popfl" : : "r" (eflags));  } -static __inline uint -read_ebp(void) -{ -        uint ebp; -        __asm __volatile("movl %%ebp,%0" : "=r" (ebp)); -        return ebp; -} - -static __inline uint -read_esp(void) -{ -        uint esp; -        __asm __volatile("movl %%esp,%0" : "=r" (esp)); -        return esp; -} - -static __inline uint -read_esi(void) -{ -        uint esi; -        __asm __volatile("movl %%esi,%0" : "=r" (esi)); -        return esi; -} - -static __inline uint -read_edi(void) -{ -        uint edi; -        __asm __volatile("movl %%edi,%0" : "=r" (edi)); -        return edi; -} - -static __inline uint -read_ebx(void) -{ -        uint ebx; -        __asm __volatile("movl %%ebx,%0" : "=r" (ebx)); -        return ebx; -} -  static __inline void  cpuid(uint info, uint *eaxp, uint *ebxp, uint *ecxp, uint *edxp)  { | 
