kvmmake() makes a complete kernel page table, matching Figure 3.3
This commit is contained in:
parent
806580d642
commit
c64aa44d7b
|
@ -86,6 +86,7 @@ int cpuid(void);
|
||||||
void exit(int);
|
void exit(int);
|
||||||
int fork(void);
|
int fork(void);
|
||||||
int growproc(int);
|
int growproc(int);
|
||||||
|
void proc_mapstacks(pagetable_t);
|
||||||
pagetable_t proc_pagetable(struct proc *);
|
pagetable_t proc_pagetable(struct proc *);
|
||||||
void proc_freepagetable(pagetable_t, uint64);
|
void proc_freepagetable(pagetable_t, uint64);
|
||||||
int kill(int);
|
int kill(int);
|
||||||
|
@ -156,7 +157,7 @@ int uartgetc(void);
|
||||||
// vm.c
|
// vm.c
|
||||||
void kvminit(void);
|
void kvminit(void);
|
||||||
void kvminithart(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);
|
int mappages(pagetable_t, uint64, uint64, uint64, int);
|
||||||
pagetable_t uvmcreate(void);
|
pagetable_t uvmcreate(void);
|
||||||
void uvminit(pagetable_t, uchar *, uint);
|
void uvminit(pagetable_t, uchar *, uint);
|
||||||
|
|
|
@ -21,6 +21,23 @@ static void freeproc(struct proc *p);
|
||||||
|
|
||||||
extern char trampoline[]; // trampoline.S
|
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.
|
// initialize the proc table at boot time.
|
||||||
void
|
void
|
||||||
procinit(void)
|
procinit(void)
|
||||||
|
@ -30,18 +47,8 @@ procinit(void)
|
||||||
initlock(&pid_lock, "nextpid");
|
initlock(&pid_lock, "nextpid");
|
||||||
for(p = proc; p < &proc[NPROC]; p++) {
|
for(p = proc; p < &proc[NPROC]; p++) {
|
||||||
initlock(&p->lock, "proc");
|
initlock(&p->lock, "proc");
|
||||||
|
p->kstack = KSTACK((int) (p - 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;
|
|
||||||
}
|
}
|
||||||
kvminithart();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must be called with interrupts disabled,
|
// Must be called with interrupts disabled,
|
||||||
|
|
42
kernel/vm.c
42
kernel/vm.c
|
@ -15,33 +15,45 @@ extern char etext[]; // kernel.ld sets this to end of kernel code.
|
||||||
|
|
||||||
extern char trampoline[]; // trampoline.S
|
extern char trampoline[]; // trampoline.S
|
||||||
|
|
||||||
/*
|
// Make a direct-map page table for the kernel.
|
||||||
* create a direct-map page table for the kernel.
|
pagetable_t
|
||||||
*/
|
kvmmake(void)
|
||||||
void
|
|
||||||
kvminit()
|
|
||||||
{
|
{
|
||||||
kernel_pagetable = (pagetable_t) kalloc();
|
pagetable_t kpgtbl;
|
||||||
memset(kernel_pagetable, 0, PGSIZE);
|
|
||||||
|
kpgtbl = (pagetable_t) kalloc();
|
||||||
|
memset(kpgtbl, 0, PGSIZE);
|
||||||
|
|
||||||
// uart registers
|
// uart registers
|
||||||
kvmmap(UART0, UART0, PGSIZE, PTE_R | PTE_W);
|
kvmmap(kpgtbl, UART0, UART0, PGSIZE, PTE_R | PTE_W);
|
||||||
|
|
||||||
// virtio mmio disk interface
|
// virtio mmio disk interface
|
||||||
kvmmap(VIRTIO0, VIRTIO0, PGSIZE, PTE_R | PTE_W);
|
kvmmap(kpgtbl, VIRTIO0, VIRTIO0, PGSIZE, PTE_R | PTE_W);
|
||||||
|
|
||||||
// PLIC
|
// 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.
|
// 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.
|
// 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
|
// map the trampoline for trap entry/exit to
|
||||||
// the highest virtual address in the kernel.
|
// 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,
|
// 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.
|
// only used when booting.
|
||||||
// does not flush TLB or enable paging.
|
// does not flush TLB or enable paging.
|
||||||
void
|
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");
|
panic("kvmmap");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue