Lab3 page tables

  1. Print a page table
    添加一個(gè)打印頁(yè)表的內(nèi)核函數(shù),參考遞歸釋放頁(yè)表的函數(shù)freewalk(),
    vm.c
static char * prefix[3] = {"..", ".. ..", ".. .. .."};
int
pgtblprint(pagetable_t pagetable, int level) {
  if (level > 2) {
    return 0;
  }

  for (int i = 0; i < 512; i++) {
    pte_t pte = pagetable[i];
    if (pte & PTE_V) {
      uint64 pa = PTE2PA(pte);
      printf("%s%d: pte %p pa %p\n", prefix[level], i, pte, pa);

      if ((pte & (PTE_R|PTE_W|PTE_X)) == 0) {
        uint64 child = PTE2PA(pte);
        pgtblprint((pagetable_t)child, level + 1);
      }
    }
  }

  return 0;
}

int
vmprint(pagetable_t pagetable) {
  printf("page table %p\n", pagetable);
  return pgtblprint(pagetable, 0);
}

defs.h

int             vmprint(pagetable_t pagetable);

exec.c

vmprint(p->pagetable);

測(cè)試結(jié)果


pte-2.PNG
  1. A kernel page table per process
    每個(gè)進(jìn)程進(jìn)入內(nèi)核時(shí),都擁有自己的內(nèi)核頁(yè)表
    proc.h
    進(jìn)程結(jié)構(gòu)體struct proc結(jié)構(gòu)體增加內(nèi)核頁(yè)表字段
pagetable_t kernelpagetable; // kernel page table

vm.c
增加proc_kvminit函數(shù),創(chuàng)建頁(yè)表,并修改kvminit

void
kvminit()
{
  kernel_pagetable = proc_kvminit();
  
  // CLINT
  uvmmap(kernel_pagetable, CLINT, CLINT, 0x10000, PTE_R | PTE_W);
}

pagetable_t
proc_kvminit()
{
  pagetable_t kernelpagetable = uvmcreate();
  if (kernelpagetable == 0) {
    return 0;
  }

  uvmmap(kernelpagetable, UART0, UART0, PGSIZE, PTE_R | PTE_W);
  uvmmap(kernelpagetable, VIRTIO0, VIRTIO0, PGSIZE, PTE_R | PTE_W);
  // uvmmap(kernelpagetable, CLINT, CLINT, 0x10000, PTE_R | PTE_W);
  uvmmap(kernelpagetable, PLIC, PLIC, 0x400000, PTE_R | PTE_W);
  uvmmap(kernelpagetable, KERNBASE, KERNBASE, (uint64)etext-KERNBASE, PTE_R | PTE_X);
  uvmmap(kernelpagetable, (uint64)etext, (uint64)etext, PHYSTOP-(uint64)etext, PTE_R | PTE_W);
  uvmmap(kernelpagetable, TRAMPOLINE, (uint64)trampoline, PGSIZE, PTE_R | PTE_X);
  return kernelpagetable;
}

void uvmmap(pagetable_t pagetable, uint64 va, uint64 pa, uint64 sz, int perm)
{
  if (mappages(pagetable, va, sz, pa, perm)) {
    panic("uvmmap");
  }
}

創(chuàng)建進(jìn)程的時(shí)候,為進(jìn)程分配獨(dú)立的頁(yè)表,以及內(nèi)核棧
proc.c

p->kernelpagetable = proc_kvminit();
  char *pa = kalloc();
  if (pa == 0) {
    panic("kalloc");
  }
  uint64 va = TRAMPOLINE - 2*PGSIZE;
  uvmmap(p->kernelpagetable, va, (uint64)pa, PGSIZE, PTE_R | PTE_W);
  p->kstack = va;

在調(diào)度器調(diào)度進(jìn)程時(shí),切換到該進(jìn)程對(duì)應(yīng)的內(nèi)核頁(yè)表
proc.c

// 切換到進(jìn)程獨(dú)立的內(nèi)核頁(yè)表
        w_satp(MAKE_SATP(p->kernelpagetable));
        sfence_vma();

        swtch(&c->context, &p->context);

        // 切換到全局內(nèi)核頁(yè)表
        kvminithart();

進(jìn)程結(jié)束時(shí),釋放進(jìn)程獨(dú)享的頁(yè)表以及內(nèi)核棧
proc.c

// 釋放進(jìn)程的內(nèi)核棧
  if (p->kstack) {
    pte_t* pte = walk(p->kernelpagetable, p->kstack, 0);
    if (pte == 0) {
      panic("freeproc: walk");
    }
    kfree((void*)PTE2PA(*pte));
  }
  p->kstack = 0;

  if (p->kernelpagetable) {
    kvm_free_kernelpagetable(p->kernelpagetable);
  }

vm.c

void 
kvm_free_kernelpagetable(pagetable_t pagetable)
{
  for (int i = 0; i < 512; i++) {
    pte_t pte = pagetable[i];
    if ((pte & PTE_V)) {
      pagetable[i] = 0;
      if ((pte & (PTE_R|PTE_W|PTE_X)) == 0) {
        uint64 child = PTE2PA(pte);
        kvm_free_kernelpagetable((pagetable_t)child);
      }
    }
  }
  kfree((void*)pagetable);
}

測(cè)試結(jié)果:


usertest1.PNG
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 為什么需要虛擬內(nèi)存 shell進(jìn)程由于bug,引發(fā)了隨機(jī)寫入某些內(nèi)存地址,這些內(nèi)存地址可能是其他進(jìn)程使用的,而可能...
    西部小籠包閱讀 488評(píng)論 0 0
  • 操作系統(tǒng)的隔離性 如果沒(méi)有操作系統(tǒng),應(yīng)用程序會(huì)直接與硬件交互。比如,應(yīng)用程序可以直接看到CPU的多個(gè)核,看到磁盤,...
    西部小籠包閱讀 559評(píng)論 0 0
  • 實(shí)驗(yàn)三:虛擬內(nèi)存管理 專業(yè)班級(jí): 學(xué)號(hào): 姓名: 上課老師: 一、實(shí)驗(yàn)?zāi)康?1.了解虛擬內(nèi)存的Page Fault...
    北北南北閱讀 2,157評(píng)論 0 2
  • 頁(yè)表是操作系統(tǒng)給每個(gè)進(jìn)程提供私有地址空間和內(nèi)存的一種機(jī)制。頁(yè)表決定內(nèi)存地址的意義以及哪些物理內(nèi)存能夠訪問(wèn)。他們?cè)试S...
    sarto閱讀 3,037評(píng)論 0 0
  • linux資料總章2.1 1.0寫的不好抱歉 但是2.0已經(jīng)改了很多 但是錯(cuò)誤還是無(wú)法避免 以后資料會(huì)慢慢更新 大...
    數(shù)據(jù)革命閱讀 13,189評(píng)論 2 33

友情鏈接更多精彩內(nèi)容