void freerange(void *pa_start, void *pa_end) { char *p; p = (char*)PGROUNDUP((uint64)pa_start); for(; p + PGSIZE <= (char*)pa_end; p += PGSIZE) kfree(p); }
在这部分代码中,从内存的下界到内存的上界,调用kfree函数释放内存页,使其可以被重新分配和使用。
内核页表初始化
1 2 3 4 5 6 7 8 9
// add a mapping to the kernel page table. // only used when booting. // does not flush TLB or enable paging. void kvmmap(pagetable_t kpgtbl, uint64 va, uint64 pa, uint64 sz, int perm) { if(mappages(kpgtbl, va, sz, pa, perm) != 0) panic("kvmmap"); }
// map kernel data and the physical RAM we'll make use of. 内核数据及其后的物理内存区域 kvmmap(kpgtbl, (uint64)etext, (uint64)etext, PHYSTOP-(uint64)etext, PTE_R | PTE_W);
// map the trampoline for trap entry/exit to 中断入口/出口的trampoline代码映射了一个页面,它位于内核的最高虚拟地址。 // the highest virtual address in the kernel. kvmmap(kpgtbl, TRAMPOLINE, (uint64)trampoline, PGSIZE, PTE_R | PTE_X);
# kernel/file.h // in-memory copy of an inode structinode { uint dev; // Device number uint inum; // Inode number int ref; // Reference count structsleeplocklock;// protects everything below here int valid; // inode has been read from disk?
short type; // copy of disk inode short major; short minor; short nlink; uint size; uint addrs[NDIRECT+1]; };
// Set up first user process. void userinit(void) { structproc *p;
p = allocproc(); initproc = p; // allocate one user page and copy init's instructions // and data into it. uvminit(p->pagetable, initcode, sizeof(initcode)); p->sz = PGSIZE;
// prepare for the very first "return" from kernel to user. p->trapframe->epc = 0; // user program counter p->trapframe->sp = PGSIZE; // user stack pointer