XV6 Lab: page tables

XV6 Lab: page tables

文章目录

  • XV6 Lab: page tables
  • 一、vscode调试xv6代码
  • 二、调试过程
    • 1. kinit();
    • 2. kvminit();
  • 总结

一、vscode调试xv6代码

参考

二、调试过程

1. kinit();

void
kinit()
{
  initlock(&kmem.lock, "kmem");
  freerange(end, (void*)PHYSTOP);
}

对于end变量的赋值是通过kernel.ld确定的。(链接脚本)
对于PHYSTOP变量,是通过memlayout.h定义的。
跟进freerange()函数会发现,我们可以分配的物理内存大概是0x80026240~0x88000000XV6 Lab: page tables_第1张图片
我们把这一大段内存通过链表遍历的方式管理起来,链表上每个节点的间隔是一个页面的大小4096(0x1000)。链表用全局变量kmem保存。
kinit(); 函数执行完。我们可以观察kmem->freelist的值。我们会发现这样的等式
0x87fff000 + 0x1000 = pa_end
在这里插入图片描述
同时还可以简单的遍历这个链表。由此可见物理内存已经被kmem这样的链表记录下来。
XV6 Lab: page tables_第2张图片

2. kvminit();

该函数的作用是:创建kernel_pagetable。
这里调用了kalloc()函数,该函数的作用就是遍历keme链表把物理内存一页一页的分配。
可以观察到kpgtbl的值等于刚刚kmem->freelist的值。
在这里插入图片描述
这里是内核的内存映射过程。建立虚拟地址和物理地址的转换过程。

  kvmmap(kpgtbl, UART0, UART0, PGSIZE, PTE_R | PTE_W);

  // virtio mmio disk interface
  kvmmap(kpgtbl, VIRTIO0, VIRTIO0, PGSIZE, PTE_R | PTE_W);

  // PLIC
  kvmmap(kpgtbl, PLIC, PLIC, 0x400000, PTE_R | PTE_W);

  // map kernel text executable and read-only.
  kvmmap(kpgtbl, KERNBASE, KERNBASE, (uint64)etext-KERNBASE, PTE_R | PTE_X);

  // 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
  // the highest virtual address in the kernel.
  kvmmap(kpgtbl, TRAMPOLINE, (uint64)trampoline, PGSIZE, PTE_R | PTE_X);

总结

未完待续。

你可能感兴趣的:(OS,编程语言)