Merge branch 'master' of git+ssh://amsterdam.csail.mit.edu/home/am0/6.828/xv6
Conflicts: vm.c
This commit is contained in:
commit
62e3b8a92c
9 changed files with 67 additions and 57 deletions
|
@ -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
|
||||||
|
|
19
log.c
19
log.c
|
@ -76,12 +76,11 @@ 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,10 +143,10 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
acquire(&log.lock);
|
acquire(&log.lock);
|
||||||
|
|
17
main.c
17
main.c
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
12
mmu.h
12
mmu.h
|
@ -118,13 +118,13 @@ 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)
|
||||||
#define PTXSHIFT 12 // offset of PTX in a linear address
|
#define PTXSHIFT 12 // offset of PTX in a linear address
|
||||||
#define PDXSHIFT 22 // offset of PDX in a linear address
|
#define PDXSHIFT 22 // offset of PDX in a linear address
|
||||||
|
|
||||||
#define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1))
|
#define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1))
|
||||||
#define PGROUNDDOWN(a) (((a)) & ~(PGSIZE-1))
|
#define PGROUNDDOWN(a) (((a)) & ~(PGSIZE-1))
|
||||||
|
|
16
runoff.list
16
runoff.list
|
@ -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
|
||||||
|
|
||||||
|
|
6
string.c
6
string.c
|
@ -4,7 +4,11 @@
|
||||||
void*
|
void*
|
||||||
memset(void *dst, int c, uint n)
|
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;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
32
vm.c
32
vm.c
|
@ -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
9
x86.h
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue