summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrans Kaashoek <[email protected]>2020-10-14 20:03:14 -0400
committerFrans Kaashoek <[email protected]>2020-10-14 20:28:16 -0400
commitd4cecb269f2acc61cc1adc11fec2aa690b9c553b (patch)
tree810d6d0ab6ee7c31b42d0635e7f91ba5722cab92
parent21cfc978096c3ffa2fdd3bde4e698482a5dff6c3 (diff)
downloadxv6-labs-d4cecb269f2acc61cc1adc11fec2aa690b9c553b.tar.gz
xv6-labs-d4cecb269f2acc61cc1adc11fec2aa690b9c553b.tar.bz2
xv6-labs-d4cecb269f2acc61cc1adc11fec2aa690b9c553b.zip
kvmmake() makes a complete kernel page table, matching Figure 3.3
-rw-r--r--kernel/defs.h3
-rw-r--r--kernel/proc.c29
-rw-r--r--kernel/vm.c42
3 files changed, 47 insertions, 27 deletions
diff --git a/kernel/defs.h b/kernel/defs.h
index 49aafdd..41098f4 100644
--- a/kernel/defs.h
+++ b/kernel/defs.h
@@ -86,6 +86,7 @@ int cpuid(void);
void exit(int);
int fork(void);
int growproc(int);
+void proc_mapstacks(pagetable_t);
pagetable_t proc_pagetable(struct proc *);
void proc_freepagetable(pagetable_t, uint64);
int kill(int);
@@ -156,7 +157,7 @@ int uartgetc(void);
// vm.c
void kvminit(void);
void kvminithart(void);
-void kvmmap(uint64, uint64, uint64, int);
+void kvmmap(pagetable_t, uint64, uint64, uint64, int);
int mappages(pagetable_t, uint64, uint64, uint64, int);
pagetable_t uvmcreate(void);
void uvminit(pagetable_t, uchar *, uint);
diff --git a/kernel/proc.c b/kernel/proc.c
index 56314e5..d847c43 100644
--- a/kernel/proc.c
+++ b/kernel/proc.c
@@ -21,6 +21,23 @@ static void freeproc(struct proc *p);
extern char trampoline[]; // trampoline.S
+
+// Allocate a page for each process's kernel stack.
+// Map it high in memory, followed by an invalid
+// guard page.
+void
+proc_mapstacks(pagetable_t kpgtbl) {
+ struct proc *p;
+
+ for(p = proc; p < &proc[NPROC]; p++) {
+ char *pa = kalloc();
+ if(pa == 0)
+ panic("kalloc");
+ uint64 va = KSTACK((int) (p - proc));
+ kvmmap(kpgtbl, va, (uint64)pa, PGSIZE, PTE_R | PTE_W);
+ }
+}
+
// initialize the proc table at boot time.
void
procinit(void)
@@ -30,18 +47,8 @@ procinit(void)
initlock(&pid_lock, "nextpid");
for(p = proc; p < &proc[NPROC]; p++) {
initlock(&p->lock, "proc");
-
- // Allocate a page for the process's kernel stack.
- // Map it high in memory, followed by an invalid
- // guard page.
- char *pa = kalloc();
- if(pa == 0)
- panic("kalloc");
- uint64 va = KSTACK((int) (p - proc));
- kvmmap(va, (uint64)pa, PGSIZE, PTE_R | PTE_W);
- p->kstack = va;
+ p->kstack = KSTACK((int) (p - proc));
}
- kvminithart();
}
// Must be called with interrupts disabled,
diff --git a/kernel/vm.c b/kernel/vm.c
index bd53fd7..b47f111 100644
--- a/kernel/vm.c
+++ b/kernel/vm.c
@@ -15,33 +15,45 @@ extern char etext[]; // kernel.ld sets this to end of kernel code.
extern char trampoline[]; // trampoline.S
-/*
- * create a direct-map page table for the kernel.
- */
-void
-kvminit()
+// Make a direct-map page table for the kernel.
+pagetable_t
+kvmmake(void)
{
- kernel_pagetable = (pagetable_t) kalloc();
- memset(kernel_pagetable, 0, PGSIZE);
+ pagetable_t kpgtbl;
+
+ kpgtbl = (pagetable_t) kalloc();
+ memset(kpgtbl, 0, PGSIZE);
// uart registers
- kvmmap(UART0, UART0, PGSIZE, PTE_R | PTE_W);
+ kvmmap(kpgtbl, UART0, UART0, PGSIZE, PTE_R | PTE_W);
// virtio mmio disk interface
- kvmmap(VIRTIO0, VIRTIO0, PGSIZE, PTE_R | PTE_W);
+ kvmmap(kpgtbl, VIRTIO0, VIRTIO0, PGSIZE, PTE_R | PTE_W);
// PLIC
- kvmmap(PLIC, PLIC, 0x400000, PTE_R | PTE_W);
+ kvmmap(kpgtbl, PLIC, PLIC, 0x400000, PTE_R | PTE_W);
// map kernel text executable and read-only.
- kvmmap(KERNBASE, KERNBASE, (uint64)etext-KERNBASE, PTE_R | PTE_X);
+ kvmmap(kpgtbl, KERNBASE, KERNBASE, (uint64)etext-KERNBASE, PTE_R | PTE_X);
// map kernel data and the physical RAM we'll make use of.
- kvmmap((uint64)etext, (uint64)etext, PHYSTOP-(uint64)etext, PTE_R | PTE_W);
+ kvmmap(kpgtbl, (uint64)etext, (uint64)etext, PHYSTOP-(uint64)etext, PTE_R | PTE_W);
// map the trampoline for trap entry/exit to
// the highest virtual address in the kernel.
- kvmmap(TRAMPOLINE, (uint64)trampoline, PGSIZE, PTE_R | PTE_X);
+ kvmmap(kpgtbl, TRAMPOLINE, (uint64)trampoline, PGSIZE, PTE_R | PTE_X);
+
+ // map kernel stacks
+ proc_mapstacks(kpgtbl);
+
+ return kpgtbl;
+}
+
+// Initialize the one kernel_pagetable
+void
+kvminit(void)
+{
+ kernel_pagetable = kvmmake();
}
// Switch h/w page table register to the kernel's page table,
@@ -112,9 +124,9 @@ walkaddr(pagetable_t pagetable, uint64 va)
// only used when booting.
// does not flush TLB or enable paging.
void
-kvmmap(uint64 va, uint64 pa, uint64 sz, int perm)
+kvmmap(pagetable_t kpgtbl, uint64 va, uint64 pa, uint64 sz, int perm)
{
- if(mappages(kernel_pagetable, va, sz, pa, perm) != 0)
+ if(mappages(kpgtbl, va, sz, pa, perm) != 0)
panic("kvmmap");
}