diff options
| author | Frans Kaashoek <kaashoek@40.sub-75-213-160.myvzw.com> | 2011-08-11 12:25:10 -0400 | 
|---|---|---|
| committer | Frans Kaashoek <kaashoek@40.sub-75-213-160.myvzw.com> | 2011-08-11 12:25:10 -0400 | 
| commit | bd71a45046eb13797284216c43353b9b6c92f18c (patch) | |
| tree | d8dd23644bd69d3abd91daf688998b2a9b0df1d4 | |
| parent | 673b739d314b77532f0c60d0eaed4b518b912694 (diff) | |
| download | xv6-labs-bd71a45046eb13797284216c43353b9b6c92f18c.tar.gz xv6-labs-bd71a45046eb13797284216c43353b9b6c92f18c.tar.bz2 xv6-labs-bd71a45046eb13797284216c43353b9b6c92f18c.zip | |
Make AP processors boot using bootpgdir
Remove device mapping from bootpgdir
Remove unnecessary vmenable
Set CPUS back to 2 in Makefile
Passes all usertests
| -rw-r--r-- | Makefile | 10 | ||||
| -rw-r--r-- | bootother.S | 29 | ||||
| -rw-r--r-- | lapic.c | 1 | ||||
| -rw-r--r-- | main.c | 37 | ||||
| -rw-r--r-- | vm.c | 30 | 
5 files changed, 42 insertions, 65 deletions
| @@ -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 diff --git a/bootother.S b/bootother.S index 7b0b815..56edac2 100644 --- a/bootother.S +++ b/bootother.S @@ -14,12 +14,13 @@  # 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 + @@ -52,7 +52,6 @@ lapicw(int index, int value)  void  lapicinit(int c)  { -  cprintf("lapicinit: %d 0x%x\n", c, lapic);    if(!lapic)       return; @@ -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 @@ -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 | 
