diff options
| -rw-r--r-- | entryother.S | 9 | ||||
| -rw-r--r-- | log.c | 19 | ||||
| -rw-r--r-- | main.c | 17 | ||||
| -rw-r--r-- | memlayout.h | 4 | ||||
| -rw-r--r-- | mmu.h | 12 | ||||
| -rw-r--r-- | runoff.list | 16 | ||||
| -rw-r--r-- | string.c | 6 | ||||
| -rw-r--r-- | vm.c | 32 | ||||
| -rw-r--r-- | x86.h | 9 | 
9 files changed, 67 insertions, 57 deletions
| diff --git a/entryother.S b/entryother.S index 1dfbb1a..a24eaf6 100644 --- a/entryother.S +++ b/entryother.S @@ -12,11 +12,10 @@  # at an address in the low 2^16 bytes.  #  # 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, -# the address of the place to jump to (mpenter) in start-8, and the physical -# address of enterpgdir in start-12. -# +# It copies this code (start) at 0x7000.  It puts the address of +# a newly allocated per-core stack in start-4,the address of the +# place to jump to (mpenter) in start-8, and the physical address +# of enterpgdir in start-12.  #  # This code is identical to bootasm.S except:  #   - it does not need to enable A20 @@ -76,12 +76,11 @@ install_trans(void)    //if (log.lh.n > 0)    //  cprintf("install_trans %d\n", log.lh.n);    for (tail = 0; tail < log.lh.n; tail++) { -    // cprintf("put entry %d to disk block %d\n", tail, log.lh.sector[tail]); -    struct buf *lbuf = bread(log.dev, log.start+tail+1);   // read i'th block from log -    struct buf *dbuf = bread(log.dev, log.lh.sector[tail]);  // read dst block -    memmove(dbuf->data, lbuf->data, BSIZE); -    bwrite(dbuf); -    brelse(lbuf); +    struct buf *lbuf = bread(log.dev, log.start+tail+1); // read log block +    struct buf *dbuf = bread(log.dev, log.lh.sector[tail]); // read dst +    memmove(dbuf->data, lbuf->data, BSIZE);  // copy block to dst +    bwrite(dbuf);  // flush dst to disk +    brelse(lbuf);       brelse(dbuf);    }  } @@ -102,7 +101,7 @@ read_head(void)    //  cprintf("read_head: %d\n", log.lh.n);  } -// Write the in-memory log header to disk, committing log entries till head +// Write in-memory log header to disk, committing log entries till head  static void  write_head(void)  { @@ -144,10 +143,10 @@ void  commit_trans(void)  {    if (log.lh.n > 0) { -    write_head();        // This causes all blocks till log.head to be commited -    install_trans();     // Install all the transactions till head +    write_head();    // Causes all blocks till log.head to be commited +    install_trans(); // Install all the transactions till head      log.lh.n = 0;  -    write_head();        // Reclaim log +    write_head();    // Reclaim log    }    acquire(&log.lock); @@ -33,7 +33,7 @@ main(void)    ideinit();       // disk    if(!ismp)      timerinit();   // uniprocessor timer -  startothers();    // start other processors (must come before kinit; must use enter_alloc) +  startothers();    // start other processors (must come before kinit)    kinit();         // initialize memory allocator    userinit();      // first user process  (must come after kinit)    // Finish setting up this processor in mpmain. @@ -81,13 +81,14 @@ startothers(void)      if(c == cpus+cpunum())  // We've started already.        continue; -    // Tell entryother.S what stack to use, the address of mpenter and pgdir; -    // We cannot use kpgdir yet, because the AP processor is running in low  -    // memory, so we use entrypgdir for the APs too.  kalloc can return addresses -    // above 4Mbyte (the machine may have much more physical memory than 4Mbyte), which  -    // aren't mapped by entrypgdir, so we must allocate a stack using enter_alloc(); -    // This introduces the constraint that xv6 cannot use kalloc until after these  -    // last enter_alloc invocations. +    // Tell entryother.S what stack to use, where to enter, and what  +    // pgdir to use. We cannot use kpgdir yet, because the AP processor +    // is running in low  memory, so we use entrypgdir for the APs too. +    // kalloc can return addresses above 4Mbyte (the machine may have  +    // much more physical memory than 4Mbyte), which aren't mapped by +    // entrypgdir, so we must allocate a stack using enter_alloc();  +    // this introduces the constraint that xv6 cannot use kalloc until  +    // after these last enter_alloc invocations.      stack = enter_alloc();      *(void**)(code-4) = stack + KSTACKSIZE;      *(void**)(code-8) = mpenter; diff --git a/memlayout.h b/memlayout.h index e155e07..cd4433d 100644 --- a/memlayout.h +++ b/memlayout.h @@ -1,10 +1,10 @@  // Memory layout  #define EXTMEM  0x100000            // Start of extended memory -#define PHYSTOP 0xE000000           // Top physical memory (too hard to get from E820) +#define PHYSTOP 0xE000000           // Top physical memory  #define DEVSPACE 0xFE000000         // Other devices are at high addresses -// Key addresses for address space layout (see kmap in vm.c for the layout) +// Key addresses for address space layout (see kmap in vm.c for layout)  #define KERNBASE 0x80000000         // First kernel virtual address  #define KERNLINK (KERNBASE+EXTMEM)  // Address where kernel is linked @@ -118,13 +118,13 @@ struct segdesc {  #define PGADDR(d, t, o) ((uint)((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))  // Page directory and page table constants. -#define NPDENTRIES      1024            // page directory entries per page directory -#define NPTENTRIES      1024            // page table entries per page table -#define PGSIZE          4096            // bytes mapped by a page +#define NPDENTRIES      1024    // # directory entries per page directory +#define NPTENTRIES      1024    // # PTEs per page table +#define PGSIZE          4096    // bytes mapped by a page -#define PGSHIFT         12              // log2(PGSIZE) -#define PTXSHIFT        12              // offset of PTX in a linear address -#define PDXSHIFT        22              // offset of PDX in a linear address +#define PGSHIFT         12      // log2(PGSIZE) +#define PTXSHIFT        12      // offset of PTX in a linear address +#define PDXSHIFT        22      // offset of PDX in a linear address  #define PGROUNDUP(sz)  (((sz)+PGSIZE-1) & ~(PGSIZE-1))  #define PGROUNDDOWN(a) (((a)) & ~(PGSIZE-1)) diff --git a/runoff.list b/runoff.list index ddd7062..e8884e0 100644 --- a/runoff.list +++ b/runoff.list @@ -8,10 +8,6 @@ asm.h  mmu.h  elf.h -# bootloader -bootasm.S -bootmain.c -  # entering xv6  entry.S  entryother.S @@ -22,12 +18,13 @@ spinlock.h  spinlock.c  # processes +vm.c  proc.h  proc.c  swtch.S  kalloc.c  data.S -vm.c +  # system calls  traps.h  vectors.pl @@ -45,8 +42,8 @@ fs.h  file.h  ide.c  bio.c -fs.c  log.c +fs.c  file.c  sysfile.c  exec.c @@ -54,7 +51,6 @@ exec.c  # pipes  pipe.c -  # string operations  string.c @@ -76,7 +72,7 @@ usys.S  init.c  sh.c - - - +# bootloader +bootasm.S +bootmain.c @@ -4,7 +4,11 @@  void*  memset(void *dst, int c, uint n)  { -  stosb(dst, c, n); +  if ((int)dst%4 == 0 && n%4 == 0){ +    c &= 0xFF; +    stosl(dst, (c<<24)|(c<<16)|(c<<8)|c, n/4); +  } else +    stosb(dst, c, n);    return dst;  } @@ -92,19 +92,21 @@ mappages(pde_t *pgdir, void *va, uint size, uint pa,  }  // The mappings from logical to virtual are one to one (i.e., -// segmentation doesn't do anything). -// There is one page table per process, plus one that's used -// when a CPU is not running any process (kpgdir). -// A user process uses the same page table as the kernel; the -// page protection bits prevent it from using anything other -// than its memory. +// segmentation doesn't do anything). There is one page table per +// process, plus one that's used when a CPU is not running any +// process (kpgdir). A user process uses the same page table as +// the kernel; the page protection bits prevent it from using +// anything other than its memory.  //   // setupkvm() and exec() set up every page table like this: -//   0..KERNBASE      : user memory (text, data, stack, heap), mapped to some unused phys mem -//   KERNBASE..KERNBASE+EXTMEM: mapped to 0..EXTMEM  (below extended memory) -//   KERNBASE+EXTMEM..KERNBASE+end : mapped to EXTMEM..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) +//   0..KERNBASE: user memory (text+data+stack+heap), mapped to some free +//                phys memory +//   KERNBASE..KERNBASE+EXTMEM: mapped to 0..EXTMEM (for I/O space) +//   KERNBASE+EXTMEM..KERNBASE+end: mapped to EXTMEM..end  kernel, +//                                  w. no 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  // between kernend and the end of physical memory (PHYSTOP). @@ -117,8 +119,8 @@ static struct kmap {    uint phys_end;    int perm;  } kmap[] = { -  { P2V(0), 0, 1024*1024, PTE_W},  // First 1Mbyte contains BIOS and some IO devices -  { (void *)KERNLINK, V2P(KERNLINK), V2P(data),  0},  // kernel text, rodata +  { P2V(0), 0, 1024*1024, PTE_W},  // I/O space +  { (void *)KERNLINK, V2P(KERNLINK), V2P(data),  0}, // kernel text+rodata    { data, V2P(data), PHYSTOP,  PTE_W},  // kernel data, memory    { (void*)DEVSPACE, DEVSPACE, 0, PTE_W},  // more devices  }; @@ -137,8 +139,8 @@ setupkvm(char* (*alloc)(void))    if (p2v(PHYSTOP) > (void *) DEVSPACE)      panic("PHYSTOP too high");    for(k = kmap; k < &kmap[NELEM(kmap)]; k++) -    if(mappages(pgdir, k->virt, k->phys_end - k->phys_start, (uint)k->phys_start,  -                k->perm, alloc) < 0) +    if(mappages(pgdir, k->virt, k->phys_end - k->phys_start,  +                (uint)k->phys_start, k->perm, alloc) < 0)        return 0;    return pgdir; @@ -48,6 +48,15 @@ stosb(void *addr, int data, int cnt)                 "memory", "cc");  } +static inline void +stosl(void *addr, int data, int cnt) +{ +  asm volatile("cld; rep stosl" : +               "=D" (addr), "=c" (cnt) : +               "0" (addr), "1" (cnt), "a" (data) : +               "memory", "cc"); +} +  struct segdesc;  static inline void | 
