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.
#
# 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

13
log.c
View file

@ -76,11 +76,10 @@ 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);
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,7 +143,7 @@ void
commit_trans(void)
{
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
log.lh.n = 0;
write_head(); // Reclaim log

17
main.c
View file

@ -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;

View file

@ -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

4
mmu.h
View file

@ -118,8 +118,8 @@ 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 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)

View file

@ -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

View file

@ -4,6 +4,10 @@
void*
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);
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.,
// 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;

9
x86.h
View file

@ -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