text: struct buf;
  struct context;
  struct file;
  struct inode;
  struct pipe;
  struct proc;
  struct spinlock;
  struct stat;
  
  // bio.c
  void            binit(void);
  struct buf*     bread(uint, uint);
  void            brelse(struct buf*);
  void            bwrite(struct buf*);
  
  // console.c
  void            consoleinit(void);
  void            cprintf(char*, ...);
  void            consoleintr(int(*)(void));
  void            panic(char*) __attribute__((noreturn));
  
  // exec.c
  int             exec(char*, char**);
  
  // file.c
  struct file*    filealloc(void);
  void            fileclose(struct file*);
  struct file*    filedup(struct file*);
  void            fileinit(void);
  int             fileread(struct file*, char*, int n);
  int             filestat(struct file*, struct stat*);
  int             filewrite(struct file*, char*, int n);
  
  // fs.c
  int             dirlink(struct inode*, char*, uint);
  struct inode*   dirlookup(struct inode*, char*, uint*);
  struct inode*   ialloc(uint, short);
  struct inode*   idup(struct inode*);
  void            iinit(void);
  void            ilock(struct inode*);
  void            iput(struct inode*);
  void            iunlock(struct inode*);
  void            iunlockput(struct inode*);
  void            iupdate(struct inode*);
  int             namecmp(const char*, const char*);
  struct inode*   namei(char*);
  struct inode*   nameiparent(char*, char*);
  int             readi(struct inode*, char*, uint, uint);
  void            stati(struct inode*, struct stat*);
  int             writei(struct inode*, char*, uint, uint);
  
  // ide.c
  void            ideinit(void);
  void            ideintr(void);
  void            iderw(struct buf*);
  
  // ioapic.c
  void            ioapicenable(int irq, int cpu);
  extern uchar    ioapicid;
  void            ioapicinit(void);
  
  // kalloc.c
  char*           kalloc(void);
  void            kfree(char*);
  void            kinit();
  
  // kbd.c
  void            kbdintr(void);
  
  // lapic.c
  int             cpunum(void);
  extern volatile uint*    lapic;
  void            lapiceoi(void);
  void            lapicinit(int);
  void            lapicstartap(uchar, uint);
  void            microdelay(int);
  
  // mp.c
  extern int      ismp;
  int             mpbcpu(void);
  void            mpinit(void);
  void            mpstartthem(void);
  
  // picirq.c
  void            picenable(int);
  void            picinit(void);
  
  // pipe.c
  int             pipealloc(struct file**, struct file**);
  void            pipeclose(struct pipe*, int);
  int             piperead(struct pipe*, char*, int);
  int             pipewrite(struct pipe*, char*, int);
  
  // proc.c
  struct proc*    copyproc(struct proc*);
  void            exit(void);
  int             fork(void);
  int             growproc(int);
  int             kill(int);
  void            pinit(void);
  void            procdump(void);
  void            scheduler(void) __attribute__((noreturn));
  void            sched(void);
  void            sleep(void*, struct spinlock*);
  void            userinit(void);
  int             wait(void);
  void            wakeup(void*);
  void            yield(void);
  int		thread_create(void*(), void*, uint);
  void            thread_exit(void*);
  int             thread_join(int, void**);
  void		exit_all_threads(void);
  
  // binsemaphore.c
  int 		binary_sem_create(void);
  int 		binary_sem_down(int);
  int 		binary_sem_up(int);
  int		binary_sem_clear(int);
  
  // swtch.S
  void            swtch(struct context**, struct context*);
  
  // spinlock.c
  void            acquire(struct spinlock*);
  void            getcallerpcs(void*, uint*);
  int             holding(struct spinlock*);
  void            initlock(struct spinlock*, char*);
  void            release(struct spinlock*);
  void            pushcli();
  void            popcli();
  
  // string.c
  int             memcmp(const void*, const void*, uint);
  void*           memmove(void*, const void*, uint);
  void*           memset(void*, int, uint);
  char*           safestrcpy(char*, const char*, int);
  int             strlen(const char*);
  int             strncmp(const char*, const char*, uint);
  char*           strncpy(char*, const char*, int);
  
  // syscall.c
  int             argint(int, int*);
  int             argptr(int, char**, int);
  int             argstr(int, char**);
  int             fetchint(struct proc*, uint, int*);
  int             fetchstr(struct proc*, uint, char**);
  void            syscall(void);
  
  // timer.c
  void            timerinit(void);
  
  // trap.c
  void            idtinit(void);
  extern uint     ticks;
  void            tvinit(void);
  extern struct spinlock tickslock;
  
  // uart.c
  void            uartinit(void);
  void            uartintr(void);
  void            uartputc(int);
  
  // vm.c
  void            ksegment(void);
  void            kvmalloc(void);
  void            vmenable(void);
  pde_t*          setupkvm(void);
  char*           uva2ka(pde_t*, char*);
  int             allocuvm(pde_t*, uint, uint);
  int             deallocuvm(pde_t*, uint, uint);
  void            freevm(pde_t*);
  void            inituvm(pde_t*, char*, uint);
  int             loaduvm(pde_t*, char*, struct inode *, uint, uint);
  pde_t*          copyuvm(pde_t*,uint);
  void            switchuvm(struct proc*);
  void            switchkvm();
  
  // number of elements in fixed-size array
  #define NELEM(x) (sizeof(x)/sizeof((x)[0]))
  