diff options
| author | Frans Kaashoek <kaashoek@mit.edu> | 2020-10-14 20:03:14 -0400 | 
|---|---|---|
| committer | Frans Kaashoek <kaashoek@mit.edu> | 2020-10-14 20:03:14 -0400 | 
| commit | c64aa44d7b5167f5b061b1e2fdf94d240a98b2bb (patch) | |
| tree | 4affac88b8f5076999e22b2801da710ab6fadffc | |
| parent | 806580d6423274e7b38329362f64a549e04ddbab (diff) | |
| download | xv6-labs-c64aa44d7b5167f5b061b1e2fdf94d240a98b2bb.tar.gz xv6-labs-c64aa44d7b5167f5b061b1e2fdf94d240a98b2bb.tar.bz2 xv6-labs-c64aa44d7b5167f5b061b1e2fdf94d240a98b2bb.zip | |
kvmmake() makes a complete kernel page table, matching Figure 3.3
| -rw-r--r-- | kernel/defs.h | 3 | ||||
| -rw-r--r-- | kernel/proc.c | 29 | ||||
| -rw-r--r-- | kernel/vm.c | 42 | 
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 252d97c..50245ff 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");  } | 
