]> Devi Nivas Git - cs3210-lab0.git/commitdiff
more comments
authorrsc <rsc>
Thu, 7 Sep 2006 14:12:30 +0000 (14:12 +0000)
committerrsc <rsc>
Thu, 7 Sep 2006 14:12:30 +0000 (14:12 +0000)
13 files changed:
elf.h
fs.h
kalloc.c
mkdir.c
proc.c
proc.h
setjmp.S
spinlock.c
spinlock.h
stat.h
trap.c
traps.h
x86.h

diff --git a/elf.h b/elf.h
index da18dca9ab6ac6580751b1355e0323825dc9d266..da852a9427a672ad0b0838cd0b7999fec96264a3 100644 (file)
--- a/elf.h
+++ b/elf.h
@@ -1,9 +1,8 @@
-//
-// format of an ELF executable file
-//
+// Format of an ELF executable file
 
 #define ELF_MAGIC 0x464C457FU  // "\x7FELF" in little endian
 
+// File header
 struct elfhdr {
   uint magic;  // must equal ELF_MAGIC
   uchar elf[12];
@@ -22,6 +21,7 @@ struct elfhdr {
   ushort shstrndx;
 };
 
+// Program section header
 struct proghdr {
   uint type;
   uint offset;
diff --git a/fs.h b/fs.h
index 04e0b6713cc573f64b42fa194f6e03cc7ac341d2..8687d16e2bf496e2f88a51ad4c321034632479c1 100644 (file)
--- a/fs.h
+++ b/fs.h
@@ -1,12 +1,17 @@
-// on-disk file system format
+// On-disk file system format. 
+// This header is shared between kernel and user space.
+
+// Block 0 is unused.
+// Block 1 is super block.
+// Inodes start at block 2.
 
 #define BSIZE 512  // block size
 
-// sector 1 (2nd sector)
-struct superblock{
-  uint size;
-  uint nblocks;
-  uint ninodes;
+// File system super block
+struct superblock {
+  uint size;         // Size of file system (bytes???) xxx
+  uint nblocks;      // Number of blocks
+  uint ninodes;      // Number of inodes.
 };
 
 #define NADDRS (NDIRECT+1)
@@ -15,24 +20,31 @@ struct superblock{
 #define NINDIRECT (BSIZE / sizeof(uint))
 #define MAXFILE (NDIRECT  + NINDIRECT)
 
+// On-disk inode structure
 struct dinode {
-  short type;
-  short major;
-  short minor;
-  short nlink;
-  uint size;
-  uint addrs[NADDRS];
+  short type;           // File type
+  short major;          // Major device number (T_DEV only)
+  short minor;          // Minor device number (T_DEV only)
+  short nlink;          // Number of links to inode in file system
+  uint size;            // Size of file (bytes)
+  uint addrs[NADDRS];   // Data block addresses
 };
 
-#define T_DIR 1
-#define T_FILE 2
-#define T_DEV 3
+#define T_DIR  1   // Directory
+#define T_FILE 2   // File
+#define T_DEV  3   // Special device
+
+// Inodes per block.
+#define IPB           (BSIZE / sizeof(struct dinode))
+
+// Block containing inode i
+#define IBLOCK(i)     ((i) / IPB + 2)
+
+// Bitmap bits per block
+#define BPB           (BSIZE*8)
 
-// sector 0 is unused, sector 1 is superblock, inodes start at sector 2
-#define IPB (BSIZE / sizeof(struct dinode))
-#define IBLOCK(inum) (inum / IPB + 2)   // start of inode
-#define BPB (BSIZE*8)
-#define BBLOCK(b,ninodes) (b/BPB + (ninodes/IPB) + 3)  // start of bitmap
+// Block containing bit for block b
+#define BBLOCK(b, ninodes) (b/BPB + (ninodes)/IPB + 3)
 
 #define DIRSIZ 14
 
@@ -41,4 +53,5 @@ struct dirent {
   char name[DIRSIZ];
 };
 
+extern uint rootdev;  // Device number of root file system
 
index 34a55eb40f610b3aeba4082306bd1723ea4299df..7d3ca0c5a6e514f9a4f1b4d3731e4e2fedf111e7 100644 (file)
--- a/kalloc.c
+++ b/kalloc.c
@@ -40,6 +40,10 @@ kinit(void)
   kfree(start, mem * PAGE);
 }
 
+// Free the len bytes of memory pointed at by cp,
+// which normally should have been returned by a
+// call to kalloc(cp).  (The exception is when
+// initializing the allocator; see kinit above.)
 void
 kfree(char *cp, int len)
 {
diff --git a/mkdir.c b/mkdir.c
index ece7691e88c69f98b6d8bcf9e7bae0cb14a64ee8..ac2c7a6e1fb54b73e0d05c12a12f0ebbfe040e4e 100644 (file)
--- a/mkdir.c
+++ b/mkdir.c
@@ -2,6 +2,7 @@
 #include "stat.h"
 #include "user.h"
 
+int
 main(int argc, char *argv[])
 {
   int i;
diff --git a/proc.c b/proc.c
index 06ee2fd11b2bf0b6994dec027456edb0668a078e..3b7843fc25bc8137adbd453639a73f96ccadd396 100644 (file)
--- a/proc.c
+++ b/proc.c
@@ -136,7 +136,9 @@ copyproc(struct proc *p)
   return np;
 }
 
-uint
+// Grow current process's memory by n bytes.
+// Return old size on success, -1 on failure.
+int
 growproc(int n)
 {
   struct proc *cp = curproc[cpu()];
@@ -154,6 +156,7 @@ growproc(int n)
   return cp->sz - n;
 }
 
+//PAGEBREAK: 42
 // Per-CPU process scheduler.
 // Each CPU calls scheduler() after setting itself up.
 // Scheduler never returns.  It loops, doing:
diff --git a/proc.h b/proc.h
index d29f7651453fc28e06154dc6bb4bcdea556ef01d..3f0c0068aee5f6198f14d5f21883a5e33e20cbf8 100644 (file)
--- a/proc.h
+++ b/proc.h
@@ -1,18 +1,19 @@
-// segments in proc->gdt
-#define SEG_KCODE 1 // kernel code
-#define SEG_KDATA 2 // kernel data+stack
+// Segments in proc->gdt
+#define SEG_KCODE 1  // kernel code
+#define SEG_KDATA 2  // kernel data+stack
 #define SEG_UCODE 3
 #define SEG_UDATA 4
-#define SEG_TSS   5   // this process's task state
+#define SEG_TSS   5  // this process's task state
 #define NSEGS     6
 
+// Saved registers for kernel context switches.
+// Don't need to save all the %fs etc. segment registers,
+// because they are constant across kernel contexts.
+// Save all the regular registers so we don't need to care
+// which are caller save.
+// Don't save %eax, because that's the return register.
+// The layout of jmpbuf is known to setjmp.S.
 struct jmpbuf {
-  // saved registers for kernel context switches
-  // don't need to save all the fs etc. registers because
-  // they are constant across kernel contexts
-  // save all the regular registers so we don't care which are caller save
-  // don't save eax because that's the return register
-  // layout known to setjmp.S
   int ebx;
   int ecx;
   int edx;
@@ -25,39 +26,42 @@ struct jmpbuf {
 
 enum proc_state { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
 
-struct proc{
-  char *mem;    // start of process's memory (a kernel address)
-    // process memory is laid out contiguously:
-    //   text
-    //   original data and bss
-    //   fixed-size stack
-    //   expandable heap
-  uint sz;      // user memory size
-  char *kstack; // kernel stack
-  enum proc_state state;
-  int pid;
-  int ppid;
-  void *chan; // sleep
-  int killed;
-  struct file *ofile[NOFILE];
-  struct inode *cwd;
-  struct jmpbuf jmpbuf;
-  struct trapframe *tf; // points into kstack, used to find user regs
+// Per-process state
+struct proc {
+  char *mem;                // Start of process memory (kernel address)
+  uint sz;                  // Size of process memory (bytes)
+  char *kstack;             // Bottom of kernel stack for this process
+  enum proc_state state;    // Process state
+  int pid;                  // Process ID
+  int ppid;                 // Parent pid
+  void *chan;               // If non-zero, sleeping on chan
+  int killed;               // If non-zero, have been killed
+  struct file *ofile[NOFILE];  // Open files
+  struct inode *cwd;        // Current directory
+  struct jmpbuf jmpbuf;     // Jump here to run process
+  struct trapframe *tf;     // Trap frame for current interrupt
 };
 
+// Process memory is laid out contiguously:
+//   text
+//   original data and bss
+//   fixed-size stack
+//   expandable heap
+
 extern struct proc proc[];
-extern struct proc *curproc[NCPU];  // can be NULL if no proc running.
+extern struct proc *curproc[NCPU];  // Current (running) process per CPU
 
 #define MPSTACK 512
 
+// Per-CPU state
 struct cpu {
-  uchar apicid;       // Local APIC ID
-  struct jmpbuf jmpbuf;
-  struct taskstate ts;  // only to give cpu address of kernel stack
-  struct segdesc gdt[NSEGS];
-  char mpstack[MPSTACK]; // per-cpu start-up stack
-  volatile int booted;
-  int nlock; // # of locks currently held
+  uchar apicid;               // Local APIC ID
+  struct jmpbuf jmpbuf;       // Jump here to enter scheduler
+  struct taskstate ts;        // Used by x86 to find stack for interrupt
+  struct segdesc gdt[NSEGS];  // x86 global descriptor table
+  char mpstack[MPSTACK];      // Per-CPU startup stack
+  volatile int booted;        // Has the CPU started?
+  int nlock;                  // Number of locks currently held
 };
 
 extern struct cpu cpus[NCPU];
index aee559000342e6543236abc07c179ffbe52cab4f..64c587ad2ce8ee1f5859860cb961c2bb16d9f2d4 100644 (file)
--- a/setjmp.S
+++ b/setjmp.S
@@ -1,3 +1,20 @@
+#   int  setjmp(struct jmpbuf *jmp);
+#   void longjmp(struct jmpbuf *jmp);
+# 
+# Setjmp saves its stack environment in jmp
+# for later use by longjmp.  It returns 0.
+# 
+# Longjmp restores the environment saved by
+# the last call of setjmp. It then causes 
+# execution to continue as if the call of setjmp
+# had just returned 1.
+# 
+# The caller of setjmp must not itself have
+# returned in the interim.  All accessible data
+# have values as of the time longjmp was called.
+#
+#    [Description, but not code, borrowed from Plan 9.]
+
 .globl setjmp
 setjmp:
   movl 4(%esp), %eax
@@ -9,10 +26,10 @@ setjmp:
   movl %edi, 16(%eax)
   movl %esp, 20(%eax)
   movl %ebp, 24(%eax)
-  pushl 0(%esp)   /* %eip */
+  pushl 0(%esp)   # %eip
   popl 28(%eax)
 
-  movl $0, %eax   /* return value */
+  movl $0, %eax   # return value
   ret
 
 .globl longjmp
@@ -27,8 +44,8 @@ longjmp:
   movl 20(%eax), %esp
   movl 24(%eax), %ebp
 
-  addl $4, %esp   /* pop %eip into thin air */
-  pushl 28(%eax)  /* push new %eip */
+  addl $4, %esp   # pop and discard %eip
+  pushl 28(%eax)  # push new %eip
 
-  movl $1, %eax   /* return value (appears to come from setjmp!) */
+  movl $1, %eax   # return value (appears to come from setjmp!)
   ret
index 1e68ae447a54089abf9010c757d7160e3bd18e25..486c217b4ea9278858f2cc06646378aa1d2b0857 100644 (file)
@@ -1,3 +1,5 @@
+// Mutual exclusion spin locks.
+
 #include "types.h"
 #include "defs.h"
 #include "x86.h"
@@ -16,6 +18,7 @@ initlock(struct spinlock *lock, char *name)
   lock->cpu = 0xffffffff;
 }
 
+// Record the current call stack in pcs[] by following the %ebp chain.
 void
 getcallerpcs(void *v, uint pcs[])
 {
@@ -31,6 +34,10 @@ getcallerpcs(void *v, uint pcs[])
     pcs[i] = 0;
 }
 
+// Acquire the lock.
+// Loops (spins) until the lock is acquired.
+// (Because contention is handled by spinning, must not
+// go to sleep holding any locks.)
 void
 acquire(struct spinlock *lock)
 {
@@ -44,10 +51,16 @@ acquire(struct spinlock *lock)
   while(cmpxchg(0, 1, &lock->locked) == 1)
     ;
   cpuid(0, 0, 0, 0, 0);  // memory barrier
-  getcallerpcs(&lock, lock->pcs);
+  
+  // Record info about lock acquisition for debugging.
+  // The +10 is only so that we can tell the difference
+  // between forgetting to initialize lock->cpu
+  // and holding a lock on cpu 0.
   lock->cpu = cpu() + 10;
+  getcallerpcs(&lock, lock->pcs);
 }
 
+// Release the lock.
 void
 release(struct spinlock *lock)
 {
@@ -63,6 +76,7 @@ release(struct spinlock *lock)
     sti();
 }
 
+// Check whether this cpu is holding the lock.
 int
 holding(struct spinlock *lock)
 {
index ae5ad1f5b550b327c580835e3330300bc96b5a66..1a706cfdb31542292a0e1f0936c143c8e502e7b9 100644 (file)
@@ -1,6 +1,10 @@
+// Mutual exclusion lock.
 struct spinlock {
-  char *name;
-  uint locked;
-  int cpu;
-  uint pcs[10];
+  uint locked;   // Is the lock held?
+  
+  // For debugging:
+  char *name;    // Name of lock.
+  int  cpu;      // The number of the cpu holding the lock.
+  uint pcs[10];  // The call stack (an array of program counters)
+                 // that locked the lock.
 };
diff --git a/stat.h b/stat.h
index 57a018c9dcf4f3e14d2bdb05cd1071663d6858f2..bc3a06c747ec0552e023cda856e92e6f6ca36aee 100644 (file)
--- a/stat.h
+++ b/stat.h
@@ -1,7 +1,7 @@
 struct stat {
-  int dev;
-  uint ino;
-  short type;
-  short nlink;
-  uint size;
+  int dev;     // Device number
+  uint ino;    // Inode number on device
+  short type;  // Type of file
+  short nlink; // Number of links to file
+  uint size;   // Size of file in bytes
 };
diff --git a/trap.c b/trap.c
index 4fb3039b1a40ff70f56bf17b25e6b4f5a15b4ca5..b35107f40893baa6690edbda1868a84ede67d637 100644 (file)
--- a/trap.c
+++ b/trap.c
@@ -7,11 +7,11 @@
 #include "traps.h"
 #include "syscall.h"
 
+// Interrupt descriptor table (shared by all CPUs).
 struct gatedesc idt[256];
+
 extern uint vectors[];  // in vectors.S: array of 256 entry pointers
 
-extern void trapenter(void);
-extern void trapenter1(void);
 
 void
 tvinit(void)
@@ -65,30 +65,34 @@ trap(struct trapframe *tf)
     return;
   }
 
-  if(v == (IRQ_OFFSET + IRQ_IDE)){
+  if(v == IRQ_OFFSET + IRQ_IDE){
     ide_intr();
     cli(); // prevent a waiting interrupt from overflowing stack
     lapic_eoi();
     return;
   }
 
-  if(v == (IRQ_OFFSET + IRQ_KBD)){
+  if(v == IRQ_OFFSET + IRQ_KBD){
     kbd_intr();
     cli(); // prevent a waiting interrupt from overflowing stack
     lapic_eoi();
     return;
   }
 
-  if(v == (IRQ_OFFSET + IRQ_SPURIOUS)){
+  if(v == IRQ_OFFSET + IRQ_SPURIOUS){
     cprintf("spurious interrupt from cpu %d eip %x\n", cpu(), tf->eip);
     return;  // no eoi for this one.
   }
 
   if(curproc[cpu()]) {
+    // assume process caused unexpected trap,
+    // for example by dividing by zero or dereferencing a bad pointer
     cprintf("pid %d: unhandled trap %d on cpu %d eip %x -- kill proc\n",
             curproc[cpu()]->pid, v, cpu(), tf->eip);
     proc_exit();
   }
+  
+  // otherwise it's our mistake
   cprintf("unexpected trap %d from cpu %d eip %x\n", v, cpu(), tf->eip);
   panic("trap");
 }
diff --git a/traps.h b/traps.h
index 732d8e0a1efd8119a4e91193f09e0bca379cffdf..d4a6a3ae0d1f7fd7c3fed1c023fa370b9652c701 100644 (file)
--- a/traps.h
+++ b/traps.h
@@ -1,4 +1,6 @@
-// system defined:
+// x86 trap and interrupt constants.
+
+// Processor-defined:
 #define T_DIVIDE         0      // divide error
 #define T_DEBUG          1      // debug exception
 #define T_NMI            2      // non-maskable interrupt
diff --git a/x86.h b/x86.h
index bb79d3e0bcd37ead9a75804b6372f0b061cf3ee0..ab7882a32bc377389033b206e0e3657b02bb53b8 100644 (file)
--- a/x86.h
+++ b/x86.h
@@ -1,3 +1,6 @@
+// Special assembly routines to access x86-specific
+// hardware instructions.
+
 static __inline uchar
 inb(int port)
 {
@@ -124,6 +127,7 @@ sti(void)
   __asm__ volatile("sti");
 }
 
+// Layout of the trap frame on the stack upon entry to trap.
 struct trapframe {
   // registers as pushed by pusha
   uint edi;