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.
|
||||
#
|
||||
# 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
|
||||
|
|
19
log.c
19
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);
|
||||
|
|
17
main.c
17
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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
12
mmu.h
12
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))
|
||||
|
|
16
runoff.list
16
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
|
||||
|
||||
|
|
6
string.c
6
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;
|
||||
}
|
||||
|
||||
|
|
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.,
|
||||
// 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
9
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
|
||||
|
|
Loading…
Reference in a new issue