]> Devi Nivas Git - cs3210-lab0.git/commitdiff
Make AP processors boot using bootpgdir
authorFrans Kaashoek <kaashoek@40.sub-75-213-160.myvzw.com>
Thu, 11 Aug 2011 16:25:10 +0000 (12:25 -0400)
committerFrans Kaashoek <kaashoek@40.sub-75-213-160.myvzw.com>
Thu, 11 Aug 2011 16:25:10 +0000 (12:25 -0400)
Remove device mapping from bootpgdir
Remove unnecessary vmenable
Set CPUS back to 2 in Makefile
Passes all usertests

Makefile
bootother.S
lapic.c
main.c
vm.c

index e71e6b6d82589aee0c781e0ac3aea7802841caa8..bd4fb4cc7d6974d29dc015ae68936e3b7071a872 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -98,10 +98,10 @@ bootblock: bootasm.S bootmain.c
        ./sign.pl bootblock
 
 bootother: bootother.S
-       $(CC) $(CFLAGS) -nostdinc -I. -c bootother.S
-       $(LD) $(LDFLAGS) -N -e start -Ttext 0x7000 -o bootother.out bootother.o
-       $(OBJCOPY) -S -O binary bootother.out bootother
-       $(OBJDUMP) -S bootother.o > bootother.asm
+       $(CC) $(CFLAGS) -fno-pic -nostdinc -I. -c bootother.S
+       $(LD) $(LDFLAGS) -N -e start -Ttext 0x7000 -o bootblockother.o bootother.o
+       $(OBJCOPY) -S -O binary -j .text bootblockother.o bootother
+       $(OBJDUMP) -S bootblockother.o > bootother.asm
 
 initcode: initcode.S
        $(CC) $(CFLAGS) -nostdinc -I. -c initcode.S
@@ -199,7 +199,7 @@ QEMUGDB = $(shell if $(QEMU) -help | grep -q '^-gdb'; \
        then echo "-gdb tcp::$(GDBPORT)"; \
        else echo "-s -p $(GDBPORT)"; fi)
 ifndef CPUS
-CPUS := 1
+CPUS := 2
 endif
 QEMUOPTS = -hdb fs.img xv6.img -smp $(CPUS) -m 512
 
index 7b0b815298850700247ba5af4e74a1209af9e9e8..56edac2dbf312b19059fd0e79deff859f9af4c22 100644 (file)
 # 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.
+# the address of the place to jump to (mpboot) in start-8, and the physical
+# address of bootpgdir in start-12.
+#
 #
 # 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
+#   - it uses the address at start-4, start-8, and start-12
 
 .code16           
 .globl start
@@ -37,7 +38,7 @@ start:
   movl    %eax, %cr0
 
 //PAGEBREAK!
-  ljmpl    $(SEG_KCODE<<3), $(start32+KERNBASE)
+  ljmpl    $(SEG_KCODE<<3), $(start32)
 
 .code32
 start32:
@@ -49,11 +50,18 @@ start32:
   movw    %ax, %fs
   movw    %ax, %gs
 
-  # switch to the stack allocated by bootothers()
-  movl    P2V_WO(start-4), %esp
+  # Use bootpgdir as our initial page table
+  movl    (start-12), %eax
+  movl    %eax, %cr3
+  # Turn on paging.
+  movl    %cr0, %eax
+  orl     $(CR0_PE|CR0_PG|CR0_WP), %eax
+  movl    %eax, %cr0
 
-  # call mpmain()
-  call *(P2V_WO(start)-8)
+  # Switch to the stack allocated by bootothers()
+  movl    (start-4), %esp
+  # Call mpboot()
+  call  *(start-8)
 
   movw    $0x8a00, %ax
   movw    %ax, %dx
@@ -66,10 +74,11 @@ spin:
 .p2align 2
 gdt:
   SEG_NULLASM
-  SEG_ASM(STA_X|STA_R, -KERNBASE, 0xffffffff)
-  SEG_ASM(STA_W, -KERNBASE, 0xffffffff)
+  SEG_ASM(STA_X|STA_R, 0, 0xffffffff)
+  SEG_ASM(STA_W, 0, 0xffffffff)
 
 
 gdtdesc:
   .word   (gdtdesc - gdt - 1)
   .long   gdt
+
diff --git a/lapic.c b/lapic.c
index 5a758be71d5e366c7ae8cc9deadf6cccbdfffba0..7554f73813d18372de114733f49993b5c03fe879 100644 (file)
--- a/lapic.c
+++ b/lapic.c
@@ -52,7 +52,6 @@ lapicw(int index, int value)
 void
 lapicinit(int c)
 {
-  cprintf("lapicinit: %d 0x%x\n", c, lapic);
   if(!lapic) 
     return;
 
diff --git a/main.c b/main.c
index 416723e6cb0cff31f8e41ed5b064960961be9e52..dabca19644168d788c84ed7d1a67c5eac83837dd 100644 (file)
--- a/main.c
+++ b/main.c
@@ -8,7 +8,7 @@
 
 static void bootothers(void);
 static void mpmain(void)  __attribute__((noreturn));
-static volatile int newpgdir;
+extern pde_t *kpgdir;
 
 // Bootstrap processor starts running C code here.
 // Allocate a real stack and switch to it, first
@@ -21,7 +21,6 @@ main(void)
   lapicinit(mpbcpu());
   seginit();       // set up segments
   cprintf("\ncpu%d: starting xv6\n\n", cpu->id);
-  kinit();         // initialize memory allocator
   picinit();       // interrupt controller
   ioapicinit();    // another interrupt controller
   consoleinit();   // I/O devices & their interrupts
@@ -34,39 +33,35 @@ main(void)
   ideinit();       // disk
   if(!ismp)
     timerinit();   // uniprocessor timer
-  userinit();      // first user process
-  bootothers();    // start other processors
-  newpgdir = 1;
+  bootothers();    // start other processors (must come before kinit; must use boot_alloc)
+  kinit();         // initialize memory allocator
+  userinit();      // first user process  (must come after kinit)
   // Finish setting up this processor in mpmain.
   mpmain();
 }
 
-// Common CPU setup code.
-// Bootstrap CPU comes here from mainc().
 // Other CPUs jump here from bootother.S.
 static void
 mpboot(void)
 {
-  vmenable();        // turn on paging
+  switchkvm(); 
   seginit();
   lapicinit(cpunum());
   mpmain();
 }
 
 // Common CPU setup code.
-// Bootstrap CPU comes here from mainc().
-// Other CPUs jump here from bootother.S.
 static void
 mpmain(void)
 {
   cprintf("cpu%d: starting\n", cpu->id);
   idtinit();       // load idt register
   xchg(&cpu->booted, 1); // tell bootothers() we're up
-  while (!newpgdir) ;  // wait until we have new page dir
-  switchkvm();     // switch to new page dir
   scheduler();     // start running processes
 }
 
+pde_t bootpgdir[];
+
 // Start the non-boot processors.
 static void
 bootothers(void)
@@ -86,41 +81,37 @@ bootothers(void)
     if(c == cpus+cpunum())  // We've started already.
       continue;
 
-    // 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();
+    // Tell bootother.S what stack to use, the address of mpboot and pgdir;
+    stack = boot_alloc();    // We need a stack below 4Mbyte with bootpgdir
     *(void**)(code-4) = stack + KSTACKSIZE;
     *(void**)(code-8) = mpboot;
+    *(int**)(code-12) = (void *) v2p(bootpgdir);
 
     lapicstartap(c->id, v2p(code));
 
-    // Wait for cpu to finish mpmain()
+    // wait for cpu to finish mpmain()
     while(c->booted == 0)
       ;
   }
 }
 
-// Boot page table used in multiboot.S.
+// Boot page table used in multiboot.S and bootother.S.
 // Page directories (and page tables), must start on a page boundary,
 // hence the "__aligned__" attribute.  Also, because of restrictions
 // related to linking and static initializers, we use "x + PTE_P"
 // here, rather than the more standard "x | PTE_P".  Everywhere else
 // you should use "|" to combine flags.
-pte_t entry_pgtable[NPTENTRIES];
 pte_t dev_pgtable[NPTENTRIES];
+pte_t entry_pgtable[NPTENTRIES];
 
 __attribute__((__aligned__(PGSIZE)))
 pde_t bootpgdir[NPDENTRIES] = {
        // Map VA's [0, 4MB) to PA's [0, 4MB)
        [0]
-               = ((uint)entry_pgtable - KERNBASE) + PTE_P,
+               = ((uint)entry_pgtable - KERNBASE) + PTE_P + PTE_W,
        // Map VA's [KERNBASE, KERNBASE+4MB) to PA's [0, 4MB)
        [KERNBASE>>PDXSHIFT]
                = ((uint)entry_pgtable - KERNBASE) + PTE_P + PTE_W,
-       // Map VA's [DEVSPACE, DEVSPACE+4MB) to PA's [DEVSPACE, 4MB)
-       [0xFEE00000>>PDXSHIFT]
-               = ((uint)dev_pgtable - KERNBASE) + PTE_P + PTE_W,
 };
 
 // XXX switch to super pages
diff --git a/vm.c b/vm.c
index fe6bb084a37cef75b1885d5e6fb0ce3810f83ca4..049a25e04efc0a1f35577c8e980c11c20da8516c 100644 (file)
--- a/vm.c
+++ b/vm.c
@@ -8,7 +8,7 @@
 #include "elf.h"
 
 extern char data[];  // defined in data.S
-static pde_t *kpgdir;  // for use in scheduler()
+pde_t *kpgdir;  // for use in scheduler()
 struct segdesc gdt[NSEGS];
 
 // Set up CPU's kernel segment descriptors.
@@ -40,7 +40,7 @@ seginit(void)
 }
 
 // Return the address of the PTE in page table pgdir
-// that corresponds to linear address va.  If create!=0,
+// that corresponds to linear address va.  If alloc!=0,
 // create any required page table pages.
 static pte_t *
 walkpgdir(pde_t *pgdir, const void *va, char* (*alloc)(void))
@@ -102,8 +102,8 @@ mappages(pde_t *pgdir, void *la, uint size, uint pa, int perm, char* (*alloc)(vo
 // setupkvm() and exec() set up every page table like this:
 //   0..USERTOP      : user memory (text, data, stack, heap), mapped to some unused phys mem
 //   KERNBASE..KERNBASE+1M: mapped to 0..1M
-//   KERNBASE+1M..KERNBASE+end : mapped to 1M..end
-//   KERNBASE+end..KERBASE+PHYSTOP     : mapped to end..PHYSTOP (free memory)
+//   KERNBASE+1M..KERNBASE+end : mapped to 1M..end (mapped without write permission)
+//   KERNBASE+end..KERBASE+PHYSTOP     : mapped to end..PHYSTOP (rw data + free memory)
 //   0xfe000000..0    : mapped direct (devices such as ioapic)
 //
 // The kernel allocates memory for its heap and for user memory
@@ -150,28 +150,6 @@ kvmalloc(void)
   switchkvm();
 }
 
-// Turn on paging.
-void
-vmenable(void)
-{
-  uint cr0;
-
-  switchkvm(); // load kpgdir into cr3
-  cr0 = rcr0();
-  cr0 |= CR0_PG;
-  lcr0(cr0);
-
- struct cpu *c = &cpus[0];
-  lgdt((void *)v2p((void *)(c->gdt)), sizeof(c->gdt));
-  loadgs(SEG_KCPU << 3);
-  loadfs(SEG_KDATA << 3);
-  loades(SEG_KDATA << 3);
-  loadds(SEG_KDATA << 3);
-  loadss(SEG_KDATA << 3);
-
-  __asm volatile("ljmp %0,$1f\n 1:\n" :: "i" (SEG_KCODE << 3));  // reload cs
-}
-
 // Switch h/w page table register to the kernel-only page table,
 // for when no process is running.
 void