初始化页表

之前我们已经在内存中为页目录表预留了空间,现在我们将
初始化页目录表,页目录表一共有1024个表项。前768个表项为用户空间预留,
后面256个表项为内核空间预留,暂时只考虑映射4G空间。在内核空间中,在main函数中,
不能通过用户空间的页表访问内核,所以,之前在head.s中设置的映射内核空间的页目录表项
作废,重新设置。
将物理地址896M转化成虚拟地址
end = (unsigned long)__va(max_low_pfn*PAGE_SIZE);

之前已经设置好了页目录表,在物理地址0x101000处
pgd_base = swapper_pg_dir;

取得虚拟地址空间中内核的起始地址的页目录索引号
i = __pgd_offset(PAGE_OFFSET);
设置内核起始虚拟地址
pgd = pgd_base + i;
从内核空间开始遍历页目录数组
for (; i < PTRS_PER_PGD; pgd++, i++) {
取虚拟地址
vaddr = i*PGDIR_SIZE;
if (end && (vaddr >= end))
  break;
掠过中间页目录地址转换过程,我们只需要映射4G内存
pmd = (pmd_t *)pgd;

if (pmd != pmd_offset(pgd, 0))
  BUG();
设置中间页目录表,我们只需要映射4G内存,因此,PTRS_PER_PMD为1,只有一个表项
for (j = 0; j < PTRS_PER_PMD; pmd++, j++) {
  因为每张页表需要1页来存储,共1024项。为页表分配一页
  pte_base = pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
  
  for (k = 0; k < PTRS_PER_PTE; pte++, k++) {
   为页表的首地址计算虚拟地址
   vaddr = i*PGDIR_SIZE + j*PMD_SIZE + k*PAGE_SIZE;
   if (end && (vaddr >= end))
    break;
   设置页表项,该页的属性:(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
   *pte = mk_pte_phys(__pa(vaddr), PAGE_KERNEL);
  }
  set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte_base)));
  if (pte_base != pte_offset(pmd, 0))
   BUG();

}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值