summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--entry.S2
-rw-r--r--memlayout.h8
-rw-r--r--vm.c41
3 files changed, 27 insertions, 24 deletions
diff --git a/entry.S b/entry.S
index 18947b0..5f4e124 100644
--- a/entry.S
+++ b/entry.S
@@ -36,7 +36,7 @@ multiboot_header:
.globl _start
_start = V2P_WO(entry)
-# Entering xv6 on boot processor. Machine is mostly set up.
+# Entering xv6 on boot processor, with paging off.
.globl entry
entry:
# Turn on page size extension for 4Mbyte pages
diff --git a/memlayout.h b/memlayout.h
index cd4433d..6a62cd7 100644
--- a/memlayout.h
+++ b/memlayout.h
@@ -10,13 +10,13 @@
#ifndef __ASSEMBLER__
-static inline uint v2p(void *a) { return (uint) a - KERNBASE; }
-static inline void *p2v(uint a) { return (void *) a + KERNBASE; }
+static inline uint v2p(void *a) { return ((uint) (a)) - KERNBASE; }
+static inline void *p2v(uint a) { return (void *) ((a) + KERNBASE); }
#endif
-#define V2P(a) ((uint) a - KERNBASE)
-#define P2V(a) ((void *) a + KERNBASE)
+#define V2P(a) (((uint) (a)) - KERNBASE)
+#define P2V(a) (((void *) (a)) + KERNBASE)
#define V2P_WO(x) ((x) - KERNBASE) // same as V2P, but without casts
#define P2V_WO(x) ((x) + KERNBASE) // same as V2P, but without casts
diff --git a/vm.c b/vm.c
index 75fbc59..a41bfa1 100644
--- a/vm.c
+++ b/vm.c
@@ -90,36 +90,39 @@ mappages(pde_t *pgdir, void *va, uint size, uint pa,
return 0;
}
-// 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 accessing kernel memory.
+// There is one page table per process, plus one that's used when
+// a CPU is not running any process (kpgdir). The kernel uses the
+// current process's page table during system calls and interrupts;
+// page protection bits prevent user code from using the kernel's
+// mappings.
//
// setupkvm() and exec() set up every page table like this:
-// 0..KERNBASE: user memory (text+data+stack+heap), mapped to some free
-// phys memory
+//
+// 0..KERNBASE: user memory (text+data+stack+heap), mapped to
+// phys memory allocated by the kernel
// 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
+// KERNBASE+EXTMEM..data: mapped to EXTMEM..V2P(data)
+// for the kernel's instructions and r/o data
+// data..KERNBASE+PHYSTOP: mapped to V2P(data)..PHYSTOP,
+// rw data + free physical memory
// 0xfe000000..0: mapped direct (devices such as ioapic)
//
-// The kernel allocates memory for its heap and for user memory
-// between KERNBASE+end and the end of physical memory (PHYSTOP).
-// The user program sits in the bottom of the address space, and the
-// kernel at the top at KERNBASE.
+// The kernel allocates physical memory for its heap and for user memory
+// between V2P(end) and the end of physical memory (PHYSTOP)
+// (directly addressable from end..P2V(PHYSTOP)).
+
+// This table defines the kernel's mappings, which are present in
+// every process's page table.
static struct kmap {
void *virt;
uint phys_start;
uint phys_end;
int perm;
} kmap[] = {
- { 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
+ { (void*) KERNBASE, 0, EXTMEM, PTE_W}, // I/O space
+ { (void*) KERNLINK, V2P(KERNLINK), V2P(data), 0}, // kernel text+rodata
+ { (void*) data, V2P(data), PHYSTOP, PTE_W}, // kernel data, memory
+ { (void*) DEVSPACE, DEVSPACE, 0, PTE_W}, // more devices
};
// Set up kernel part of a page table.