Merge branch 'master' of git+ssh://amsterdam.csail.mit.edu/home/am0/6.828/xv6

Conflicts:
	vm.c
This commit is contained in:
Robert Morris 2011-09-01 12:03:49 -04:00
commit 62e3b8a92c
9 changed files with 67 additions and 57 deletions

View file

@ -12,11 +12,10 @@
# at an address in the low 2^16 bytes. # at an address in the low 2^16 bytes.
# #
# Bootothers (in main.c) sends the STARTUPs one at a time. # Bootothers (in main.c) sends the STARTUPs one at a time.
# It copies this code (start) at 0x7000. # It copies this code (start) at 0x7000. It puts the address of
# It puts the address of a newly allocated per-core stack in start-4, # a newly allocated per-core stack in start-4,the address of the
# the address of the place to jump to (mpenter) in start-8, and the physical # place to jump to (mpenter) in start-8, and the physical address
# address of enterpgdir in start-12. # of enterpgdir in start-12.
#
# #
# This code is identical to bootasm.S except: # This code is identical to bootasm.S except:
# - it does not need to enable A20 # - it does not need to enable A20

13
log.c
View file

@ -76,11 +76,10 @@ install_trans(void)
//if (log.lh.n > 0) //if (log.lh.n > 0)
// cprintf("install_trans %d\n", log.lh.n); // cprintf("install_trans %d\n", log.lh.n);
for (tail = 0; tail < log.lh.n; tail++) { 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 log block
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
struct buf *dbuf = bread(log.dev, log.lh.sector[tail]); // read dst block memmove(dbuf->data, lbuf->data, BSIZE); // copy block to dst
memmove(dbuf->data, lbuf->data, BSIZE); bwrite(dbuf); // flush dst to disk
bwrite(dbuf);
brelse(lbuf); brelse(lbuf);
brelse(dbuf); brelse(dbuf);
} }
@ -102,7 +101,7 @@ read_head(void)
// cprintf("read_head: %d\n", log.lh.n); // 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 static void
write_head(void) write_head(void)
{ {
@ -144,7 +143,7 @@ void
commit_trans(void) commit_trans(void)
{ {
if (log.lh.n > 0) { if (log.lh.n > 0) {
write_head(); // This causes all blocks till log.head to be commited write_head(); // Causes all blocks till log.head to be commited
install_trans(); // Install all the transactions till head install_trans(); // Install all the transactions till head
log.lh.n = 0; log.lh.n = 0;
write_head(); // Reclaim log write_head(); // Reclaim log

17
main.c
View file

@ -33,7 +33,7 @@ main(void)
ideinit(); // disk ideinit(); // disk
if(!ismp) if(!ismp)
timerinit(); // uniprocessor timer 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 kinit(); // initialize memory allocator
userinit(); // first user process (must come after kinit) userinit(); // first user process (must come after kinit)
// Finish setting up this processor in mpmain. // Finish setting up this processor in mpmain.
@ -81,13 +81,14 @@ startothers(void)
if(c == cpus+cpunum()) // We've started already. if(c == cpus+cpunum()) // We've started already.
continue; continue;
// Tell entryother.S what stack to use, the address of mpenter and pgdir; // Tell entryother.S what stack to use, where to enter, and what
// We cannot use kpgdir yet, because the AP processor is running in low // pgdir to use. We cannot use kpgdir yet, because the AP processor
// memory, so we use entrypgdir for the APs too. kalloc can return addresses // is running in low memory, so we use entrypgdir for the APs too.
// above 4Mbyte (the machine may have much more physical memory than 4Mbyte), which // kalloc can return addresses above 4Mbyte (the machine may have
// aren't mapped by entrypgdir, so we must allocate a stack using enter_alloc(); // much more physical memory than 4Mbyte), which aren't mapped by
// This introduces the constraint that xv6 cannot use kalloc until after these // entrypgdir, so we must allocate a stack using enter_alloc();
// last enter_alloc invocations. // this introduces the constraint that xv6 cannot use kalloc until
// after these last enter_alloc invocations.
stack = enter_alloc(); stack = enter_alloc();
*(void**)(code-4) = stack + KSTACKSIZE; *(void**)(code-4) = stack + KSTACKSIZE;
*(void**)(code-8) = mpenter; *(void**)(code-8) = mpenter;

View file

@ -1,10 +1,10 @@
// Memory layout // Memory layout
#define EXTMEM 0x100000 // Start of extended memory #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 #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 KERNBASE 0x80000000 // First kernel virtual address
#define KERNLINK (KERNBASE+EXTMEM) // Address where kernel is linked #define KERNLINK (KERNBASE+EXTMEM) // Address where kernel is linked

4
mmu.h
View file

@ -118,8 +118,8 @@ struct segdesc {
#define PGADDR(d, t, o) ((uint)((d) << PDXSHIFT | (t) << PTXSHIFT | (o))) #define PGADDR(d, t, o) ((uint)((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))
// Page directory and page table constants. // Page directory and page table constants.
#define NPDENTRIES 1024 // page directory entries per page directory #define NPDENTRIES 1024 // # directory entries per page directory
#define NPTENTRIES 1024 // page table entries per page table #define NPTENTRIES 1024 // # PTEs per page table
#define PGSIZE 4096 // bytes mapped by a page #define PGSIZE 4096 // bytes mapped by a page
#define PGSHIFT 12 // log2(PGSIZE) #define PGSHIFT 12 // log2(PGSIZE)

View file

@ -8,10 +8,6 @@ asm.h
mmu.h mmu.h
elf.h elf.h
# bootloader
bootasm.S
bootmain.c
# entering xv6 # entering xv6
entry.S entry.S
entryother.S entryother.S
@ -22,12 +18,13 @@ spinlock.h
spinlock.c spinlock.c
# processes # processes
vm.c
proc.h proc.h
proc.c proc.c
swtch.S swtch.S
kalloc.c kalloc.c
data.S data.S
vm.c
# system calls # system calls
traps.h traps.h
vectors.pl vectors.pl
@ -45,8 +42,8 @@ fs.h
file.h file.h
ide.c ide.c
bio.c bio.c
fs.c
log.c log.c
fs.c
file.c file.c
sysfile.c sysfile.c
exec.c exec.c
@ -54,7 +51,6 @@ exec.c
# pipes # pipes
pipe.c pipe.c
# string operations # string operations
string.c string.c
@ -76,7 +72,7 @@ usys.S
init.c init.c
sh.c sh.c
# bootloader
bootasm.S
bootmain.c

View file

@ -4,6 +4,10 @@
void* void*
memset(void *dst, int c, uint n) memset(void *dst, int c, uint 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); stosb(dst, c, n);
return dst; return dst;
} }

32
vm.c
View file

@ -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., // The mappings from logical to virtual are one to one (i.e.,
// segmentation doesn't do anything). // segmentation doesn't do anything). There is one page table per
// There is one page table per process, plus one that's used // process, plus one that's used when a CPU is not running any
// when a CPU is not running any process (kpgdir). // process (kpgdir). A user process uses the same page table as
// A user process uses the same page table as the kernel; the // the kernel; the page protection bits prevent it from using
// page protection bits prevent it from using anything other // anything other than its memory.
// than its memory.
// //
// setupkvm() and exec() set up every page table like this: // setupkvm() and exec() set up every page table like this:
// 0..KERNBASE : user memory (text, data, stack, heap), mapped to some unused phys mem // 0..KERNBASE: user memory (text+data+stack+heap), mapped to some free
// KERNBASE..KERNBASE+EXTMEM: mapped to 0..EXTMEM (below extended memory) // phys memory
// KERNBASE+EXTMEM..KERNBASE+end : mapped to EXTMEM..end (mapped without write permission) // KERNBASE..KERNBASE+EXTMEM: mapped to 0..EXTMEM (for I/O space)
// KERNBASE+end..KERBASE+PHYSTOP : mapped to end..PHYSTOP (rw data + free memory) // KERNBASE+EXTMEM..KERNBASE+end: mapped to EXTMEM..end kernel,
// 0xfe000000..0 : mapped direct (devices such as ioapic) // 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 // The kernel allocates memory for its heap and for user memory
// between kernend and the end of physical memory (PHYSTOP). // between kernend and the end of physical memory (PHYSTOP).
@ -117,8 +119,8 @@ static struct kmap {
uint phys_end; uint phys_end;
int perm; int perm;
} kmap[] = { } kmap[] = {
{ P2V(0), 0, 1024*1024, PTE_W}, // First 1Mbyte contains BIOS and some IO devices { P2V(0), 0, 1024*1024, PTE_W}, // I/O space
{ (void *)KERNLINK, V2P(KERNLINK), V2P(data), 0}, // kernel text, rodata { (void *)KERNLINK, V2P(KERNLINK), V2P(data), 0}, // kernel text+rodata
{ data, V2P(data), PHYSTOP, PTE_W}, // kernel data, memory { data, V2P(data), PHYSTOP, PTE_W}, // kernel data, memory
{ (void*)DEVSPACE, DEVSPACE, 0, PTE_W}, // more devices { (void*)DEVSPACE, DEVSPACE, 0, PTE_W}, // more devices
}; };
@ -137,8 +139,8 @@ setupkvm(char* (*alloc)(void))
if (p2v(PHYSTOP) > (void *) DEVSPACE) if (p2v(PHYSTOP) > (void *) DEVSPACE)
panic("PHYSTOP too high"); panic("PHYSTOP too high");
for(k = kmap; k < &kmap[NELEM(kmap)]; k++) for(k = kmap; k < &kmap[NELEM(kmap)]; k++)
if(mappages(pgdir, k->virt, k->phys_end - k->phys_start, (uint)k->phys_start, if(mappages(pgdir, k->virt, k->phys_end - k->phys_start,
k->perm, alloc) < 0) (uint)k->phys_start, k->perm, alloc) < 0)
return 0; return 0;
return pgdir; return pgdir;

9
x86.h
View file

@ -48,6 +48,15 @@ stosb(void *addr, int data, int cnt)
"memory", "cc"); "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; struct segdesc;
static inline void static inline void