Lab3
页表实验。
这里我觉得主要关注的就是页表的初始化以及页表如何工作,涉及的函数较多,也比较复杂。
初始化流程
下面是 kernel/main.c 的 main() 代码。
初始化的流程是:
kree() 将所有物理空间初始化为一页一页,并将底部地址加入 freelist ->
kvminit() 初始化kernel_pgtbl ->
kvminithart() 初始化 satp寄存器,在riscv中satp存储一级页表的位置 ->
procinit() 初始化每一个进程的内核栈
void
main()
{
if(cpuid() == 0){
consoleinit();
#if defined(LAB_PGTBL) || defined(LAB_LOCK)
statsinit();
#endif
printfinit();
printf("\n");
printf("xv6 kernel is booting\n");
printf("\n");
kinit(); // physical page allocator
kvminit(); // create kernel page table
kvminithart(); // turn on paging
procinit(); // process table
trapinit(); // trap vectors
trapinithart(); // install kernel trap vector
plicinit(); // set up interrupt controller
plicinithart(); // ask PLIC for device interrupts
binit(); // buffer cache
iinit(); // inode cache
fileinit(); // file table
virtio_disk_init(); // emulated hard disk
#ifdef LAB_NET
pci_init();
sockinit();
#endif
userinit(); // first user process
__sync_synchronize();
started = 1;
} else {
while(started == 0)
;
__sync_synchronize();
printf("hart %d starting\n", cpuid());
kvminithart(); // turn on paging
trapinithart(); // install kernel trap vector
plicinithart(); // ask PLIC for device interrupts
}
scheduler();
}kvminit() 内核页表
kvminit() 首先通过kalloc() 为 内核页表分配一页的空间 并初始化为 *kernel_pagetable = 0.
kvmmap() 其实就是调用了一个 mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm).
mappages()的功能就是将 va虚拟地址 映射到 pa物理地址。需要注意的是,此时xv6还没开启地址翻译,因此这几个 kvmmap() 传入的参数映射都是直接映射,也就是说 va是多少,pa就是多少。
比较有趣的就是
KERNBASE:0x80000000
Trampoline: Va位于 MaxVa - PGSIZE
procinit() 进程内核栈
值得注意的是 KSTACK()返回值每次间隔两页,因为有一页作为 kstack 的空间,有一页用在Guard Page(利用页错误防止溢出导致其他页被污染,该页不会映射到物理空间,因此不会造成浪费)
每一个用户进程都有一个对应的kernel stack,在xv6里是最多 64个进程,procinit() 为每一个进程都初始化好了 kstack 。
初始化完要重新将新的内核页表存入satp寄存器。
这里就有一个疑问,就是 kernel_pagetable 里面存着每个进程的 kstack 有什么用呢?
kstack是进程的内核栈
进程栈分为用户栈和进程栈
在 user mode 下运行时使用用户栈,在 superior mode 下运行时使用内核栈
那么既然设置了satp寄存器,就意味着地址翻译开始了,那每个进程的首级页表存在哪里呢?
在proc 结构体中:
用户进程创建
用户进程的页表是如何创建的?
通过调用 proc_pagetable() 函数,创建一个用户页表
uvmcreate() 给用户页表分配了物理空间
然后在va顶部映射 trampoline,在trampoline底下映射trapfame
Last updated