From e25b74ca8069e340c3f2c267d09beed6d9328250 Mon Sep 17 00:00:00 2001 From: Frans Kaashoek Date: Thu, 1 Sep 2011 10:25:20 -0400 Subject: [PATCH 1/2] Fix layout issues for printed version --- entryother.S | 9 ++++----- log.c | 19 +++++++++---------- main.c | 17 +++++++++-------- memlayout.h | 4 ++-- mmu.h | 12 ++++++------ runoff.list | 16 ++++++---------- vm.c | 35 +++++++++++++++++++---------------- 7 files changed, 55 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 diff --git a/log.c b/log.c index 6b5c329..ef6c1e7 100644 --- a/log.c +++ b/log.c @@ -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); diff --git a/main.c b/main.c index 23e0316..2e49ec3 100644 --- a/main.c +++ b/main.c @@ -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 diff --git a/mmu.h b/mmu.h index 0da30e7..5c9ab60 100644 --- a/mmu.h +++ b/mmu.h @@ -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 diff --git a/vm.c b/vm.c index 32775a1..c7f7315 100644 --- a/vm.c +++ b/vm.c @@ -68,7 +68,8 @@ walkpgdir(pde_t *pgdir, const void *va, char* (*alloc)(void)) // physical addresses starting at pa. va and size might not // be page-aligned. static int -mappages(pde_t *pgdir, void *va, uint size, uint pa, int perm, char* (*alloc)(void)) +mappages(pde_t *pgdir, void *va, uint size, uint pa, int perm, + char* (*alloc)(void)) { char *a, *last; pte_t *pte; @@ -91,19 +92,21 @@ mappages(pde_t *pgdir, void *va, uint size, uint pa, int perm, char* (*alloc)(vo } // 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). @@ -116,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 }; @@ -136,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; From d0f3efca650eccd5179e045cd07f7d723037defc Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Thu, 1 Sep 2011 10:41:21 -0400 Subject: [PATCH 2/2] Use stosl in memset; makes boot time bearable --- string.c | 6 +++++- x86.h | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/string.c b/string.c index a557dc5..d066c18 100644 --- a/string.c +++ b/string.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; } diff --git a/x86.h b/x86.h index 828d5bc..0c3feae 100644 --- a/x86.h +++ b/x86.h @@ -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