]> Devi Nivas Git - cs3210-lab0.git/commitdiff
change some comments, maybe more informative
authorRobert Morris <rtm@csail.mit.edu>
Mon, 13 Sep 2010 19:34:44 +0000 (15:34 -0400)
committerRobert Morris <rtm@csail.mit.edu>
Mon, 13 Sep 2010 19:34:44 +0000 (15:34 -0400)
delete most comments from bootother.S (since copy of bootasm.S)
ksegment() -> seginit()
move more stuff from main() to mainc()

bootasm.S
bootother.S
defs.h
main.c
proc.c
proc.h
spinlock.c
vm.c

index 56175cefbf9c501c3e8494670d5098214af99498..f5d1678c462a9c2467d6f1a57fd3a2440bb2d3de 100644 (file)
--- a/bootasm.S
+++ b/bootasm.S
@@ -13,7 +13,7 @@
 .code16                       # Assemble for 16-bit mode
 .globl start
 start:
-  cli                         # Disable interrupts
+  cli                         # BIOS enabled interrupts ; disable
 
   # Set up the important data segment registers (DS, ES, SS).
   xorw    %ax,%ax             # Segment number zero
@@ -45,7 +45,8 @@ seta20.2:
   # Switch from real to protected mode, using a bootstrap GDT
   # and segment translation that makes virtual addresses 
   # identical to physical addresses, so that the 
-  # effective memory map does not change during the switch.
+  # effective memory map does not change after subsequent
+  # loads of segment registers.
   lgdt    gdtdesc
   movl    %cr0, %eax
   orl     $CR0_PE, %eax
@@ -57,7 +58,11 @@ seta20.2:
   # default to 32 bits after this jump.
   ljmp    $(SEG_KCODE<<3), $start32
 
-.code32                       # Assemble for 32-bit mode
+# tell the assembler to generate 0x66 prefixes for 16-bit
+# instructions like movw, and to generate 32-bit immediate
+# addresses.
+.code32
+
 start32:
   # Set up the protected-mode data segment registers
   movw    $(SEG_KDATA<<3), %ax    # Our data segment selector
index 899669ad9f8904e10bbaaf8fd7f62909e68459e3..186873e044ae5d478009d445c7cd45daa7a06ed6 100644 (file)
@@ -9,80 +9,69 @@
 # Because this code sets DS to zero, it must sit
 # at an address in the low 2^16 bytes.
 #
-# Bootothers (in main.c) sends the STARTUPs, one at a time.
-# It puts this code (start) at 0x7000.
-# It puts the correct %esp in start-4,
-# and the place to jump to in start-8.
+# Bootothers (in main.c) sends the STARTUPs one at a time.
+# It copies this code (start) at 0x7000.
+# It puts the address of a newly allocated per-core stack in start-4,
+# and the address of the place to jump to (mpmain) in start-8.
 #
 # This code is identical to bootasm.S except:
 #   - it does not need to enable A20
 #   - it uses the address at start-4 for the %esp
 #   - it jumps to the address at start-8 instead of calling bootmain
 
-#define SEG_KCODE 1  // kernel code
-#define SEG_KDATA 2  // kernel data+stack
+#define SEG_KCODE 1
+#define SEG_KDATA 2
 
-#define CR0_PE    1  // protected mode enable bit
+#define CR0_PE    1
 
-.code16                       # Assemble for 16-bit mode
+.code16           
 .globl start
 start:
-  cli                         # Disable interrupts
+  cli            
 
-  # Set up the important data segment registers (DS, ES, SS).
-  xorw    %ax,%ax             # Segment number zero
-  movw    %ax,%ds             # -> Data Segment
-  movw    %ax,%es             # -> Extra Segment
-  movw    %ax,%ss             # -> Stack Segment
+  xorw    %ax,%ax
+  movw    %ax,%ds
+  movw    %ax,%es
+  movw    %ax,%ss
 
 //PAGEBREAK!
-  # Switch from real to protected mode, using a bootstrap GDT
-  # and segment translation that makes virtual addresses 
-  # identical to physical addresses, so that the 
-  # effective memory map does not change during the switch.
   lgdt    gdtdesc
   movl    %cr0, %eax
   orl     $CR0_PE, %eax
   movl    %eax, %cr0
 
-  # This ljmp is how you load the CS (Code Segment) register.
-  # SEG_ASM produces segment descriptors with the 32-bit mode
-  # flag set (the D flag), so addresses and word operands will
-  # default to 32 bits after this jump.
   ljmp    $(SEG_KCODE<<3), $start32
 
-.code32                       # Assemble for 32-bit mode
+.code32
 start32:
-  # Set up the protected-mode data segment registers
-  movw    $(SEG_KDATA<<3), %ax    # Our data segment selector
-  movw    %ax, %ds                # -> DS: Data Segment
-  movw    %ax, %es                # -> ES: Extra Segment
-  movw    %ax, %ss                # -> SS: Stack Segment
-  movw    $0, %ax                 # Zero segments not ready for use
-  movw    %ax, %fs                # -> FS
-  movw    %ax, %gs                # -> GS
+  movw    $(SEG_KDATA<<3), %ax
+  movw    %ax, %ds
+  movw    %ax, %es
+  movw    %ax, %ss
+  movw    $0, %ax
+  movw    %ax, %fs
+  movw    %ax, %gs
 
-  # Set up the stack pointer and call into C.
+  # switch to the stack allocated by bootothers()
   movl    start-4, %esp
+
+  # call mpmain()
   call *(start-8)
 
-  # If the call returns (it shouldn't), trigger a Bochs
-  # breakpoint if running under Bochs, then loop.
-  movw    $0x8a00, %ax            # 0x8a00 -> port 0x8a00
+  movw    $0x8a00, %ax
   movw    %ax, %dx
   outw    %ax, %dx
-  movw    $0x8ae0, %ax            # 0x8ae0 -> port 0x8a00
+  movw    $0x8ae0, %ax
   outw    %ax, %dx
 spin:
   jmp     spin
 
-# Bootstrap GDT
-.p2align 2                                # force 4 byte alignment
+.p2align 2
 gdt:
-  SEG_NULLASM                             # null seg
-  SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff)   # code seg
-  SEG_ASM(STA_W, 0x0, 0xffffffff)         # data seg
+  SEG_NULLASM
+  SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff)
+  SEG_ASM(STA_W, 0x0, 0xffffffff)
 
 gdtdesc:
-  .word   (gdtdesc - gdt - 1)                            # sizeof(gdt) - 1
-  .long   gdt                             # address gdt
+  .word   (gdtdesc - gdt - 1)
+  .long   gdt
diff --git a/defs.h b/defs.h
index 93a8bc6c1cceb228bf268ed122feaa858c16155e..7408d4d7c749e05659e60815586c2d10b38f2d4e 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -152,7 +152,7 @@ void            uartintr(void);
 void            uartputc(int);
 
 // vm.c
-void            ksegment(void);
+void            seginit(void);
 void            kvmalloc(void);
 void            vmenable(void);
 pde_t*          setupkvm(void);
diff --git a/main.c b/main.c
index 8ddf261ad3cf7cda5cb7007494dc5c7b26598659..beac4da97e09fcd130384d6a3e6abd271e8abab4 100644 (file)
--- a/main.c
+++ b/main.c
@@ -11,16 +11,14 @@ void jkstack(void)  __attribute__((noreturn));
 void mainc(void);
 
 // Bootstrap processor starts running C code here.
+// Allocate a real stack and switch to it, first
+// doing some setup required for memory allocator to work.
 int
 main(void)
 {
   mpinit();        // collect info about this machine
   lapicinit(mpbcpu());
-  ksegment();      // set up segments
-  picinit();       // interrupt controller
-  ioapicinit();    // another interrupt controller
-  consoleinit();   // I/O devices & their interrupts
-  uartinit();      // serial port
+  seginit();       // set up segments
   kinit();         // initialize memory allocator
   jkstack();       // call mainc() on a properly-allocated stack 
 }
@@ -37,10 +35,16 @@ jkstack(void)
   panic("jkstack");
 }
 
+// Set up hardware and software.
+// Runs only on the boostrap processor.
 void
 mainc(void)
 {
   cprintf("\ncpu%d: starting xv6\n\n", cpu->id);
+  picinit();       // interrupt controller
+  ioapicinit();    // another interrupt controller
+  consoleinit();   // I/O devices & their interrupts
+  uartinit();      // serial port
   kvmalloc();      // initialize the kernel page table
   pinit();         // process table
   tvinit();        // trap vectors
@@ -64,16 +68,17 @@ static void
 mpmain(void)
 {
   if(cpunum() != mpbcpu()) {
-    ksegment();
+    seginit();
     lapicinit(cpunum());
   }
   vmenable();        // turn on paging
   cprintf("cpu%d: starting\n", cpu->id);
   idtinit();       // load idt register
-  xchg(&cpu->booted, 1);
+  xchg(&cpu->booted, 1); // tell bootothers() we're up
   scheduler();     // start running processes
 }
 
+// Start the non-boot processors.
 static void
 bootothers(void)
 {
@@ -91,10 +96,13 @@ bootothers(void)
     if(c == cpus+cpunum())  // We've started already.
       continue;
 
-    // Fill in %esp, %eip and start code on cpu.
+    // Tell bootother.S what stack to use and the address of mpmain;
+    // it expects to find these two addresses stored just before
+    // its first instruction.
     stack = kalloc();
     *(void**)(code-4) = stack + KSTACKSIZE;
     *(void**)(code-8) = mpmain;
+
     lapicstartap(c->id, (uint)code);
 
     // Wait for cpu to finish mpmain()
diff --git a/proc.c b/proc.c
index 6f7bdb6414128b70399884a10bf630ab38235c18..2e8a0a4fb197871dd8e5ff2346b9acda79c40c42 100644 (file)
--- a/proc.c
+++ b/proc.c
@@ -65,7 +65,8 @@ procdump(void)
 
 //PAGEBREAK: 32
 // Look in the process table for an UNUSED proc.
-// If found, change state to EMBRYO and return it.
+// If found, change state to EMBRYO and initialize
+// state required to run in the kernel.
 // Otherwise return 0.
 static struct proc*
 allocproc(void)
@@ -97,7 +98,7 @@ found:
   p->tf = (struct trapframe*)sp;
   
   // Set up new context to start executing at forkret,
-  // which returns to trapret (see below).
+  // which returns to trapret.
   sp -= 4;
   *(uint*)sp = (uint)trapret;
 
@@ -105,6 +106,7 @@ found:
   p->context = (struct context*)sp;
   memset(p->context, 0, sizeof *p->context);
   p->context->eip = (uint)forkret;
+
   return p;
 }
 
diff --git a/proc.h b/proc.h
index 4a80a28070049fe0ed31d9d1847b601b0133ef81..7ffaffb6f033f284caed4b26fad1a1a7c8cd084f 100644 (file)
--- a/proc.h
+++ b/proc.h
@@ -11,7 +11,7 @@
 // Per-CPU state
 struct cpu {
   uchar id;                    // Local APIC ID; index into cpus[] below
-  struct context *scheduler;   // Switch here to enter scheduler
+  struct context *scheduler;   // swtch() here to enter scheduler
   struct taskstate ts;         // Used by x86 to find stack for interrupt
   struct segdesc gdt[NSEGS];   // x86 global descriptor table
   volatile uint booted;        // Has the CPU started?
@@ -20,7 +20,7 @@ struct cpu {
   
   // Cpu-local storage variables; see below
   struct cpu *cpu;
-  struct proc *proc;
+  struct proc *proc;           // The currently-running process.
 };
 
 extern struct cpu cpus[NCPU];
@@ -29,13 +29,13 @@ extern int ncpu;
 // Per-CPU variables, holding pointers to the
 // current cpu and to the current process.
 // The asm suffix tells gcc to use "%gs:0" to refer to cpu
-// and "%gs:4" to refer to proc.  ksegment sets up the
+// and "%gs:4" to refer to proc.  seginit sets up the
 // %gs segment register so that %gs refers to the memory
 // holding those two variables in the local cpu's struct cpu.
 // This is similar to how thread-local variables are implemented
 // in thread libraries such as Linux pthreads.
-extern struct cpu *cpu asm("%gs:0");       // This cpu.
-extern struct proc *proc asm("%gs:4");     // Current proc on this cpu.
+extern struct cpu *cpu asm("%gs:0");       // &cpus[cpunum()]
+extern struct proc *proc asm("%gs:4");     // cpus[cpunum()].proc
 
 //PAGEBREAK: 17
 // Saved registers for kernel context switches.
@@ -61,13 +61,13 @@ enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
 // Per-process state
 struct proc {
   uint sz;                     // Size of process memory (bytes)
-  pde_t* pgdir;                // Linear address of proc's pgdir
+  pde_t* pgdir;                // Page table
   char *kstack;                // Bottom of kernel stack for this process
   enum procstate state;        // Process state
   volatile int pid;            // Process ID
   struct proc *parent;         // Parent process
   struct trapframe *tf;        // Trap frame for current syscall
-  struct context *context;     // Switch here to run process
+  struct context *context;     // swtch() here to run process
   void *chan;                  // If non-zero, sleeping on chan
   int killed;                  // If non-zero, have been killed
   struct file *ofile[NOFILE];  // Open files
index 68cfbe94af040f43f307ddd4462191bdf145893d..281748adbe61737c3ad68cbad73831c05a15e8cf 100644 (file)
@@ -23,7 +23,7 @@ initlock(struct spinlock *lk, char *name)
 void
 acquire(struct spinlock *lk)
 {
-  pushcli();
+  pushcli(); // disable interrupts to avoid deadlock.
   if(holding(lk))
     panic("acquire");
 
diff --git a/vm.c b/vm.c
index 5c6f943c6c2bec680c37ffb6f184f8ccf785e496..c57fa53d854bf1c8cb3e825f4edd366f8dfae657 100644 (file)
--- a/vm.c
+++ b/vm.c
@@ -13,7 +13,7 @@ static pde_t *kpgdir;  // for use in scheduler()
 // Set up CPU's kernel segment descriptors.
 // Run once at boot time on each CPU.
 void
-ksegment(void)
+seginit(void)
 {
   struct cpu *c;