虚拟地址转换为物理地址

应用程序只能提供一个虚拟地址,也可以通过如下方法获取物理地址,当然得调用驱动。

Linux采用页表的概念来管理虚拟空间,内核在处理虚拟地址时都必须将其转换为物理地址,然后处理器才能够访问。虚拟地址可以通过Linux的页表操作宏逐层查找到物理地址,简单来说需要将虚拟地址分段,每段地址都作为索引指向页表,最后一级页表指向物理地址。
 Linux在2.6.11以后版本为了兼容各种处理器,采用四级页表结构:
 PGD:Page Global Directory,页全局目录,是顶级页表。
 PUD:Page Upper Directory,页上级目录,是第二级页表
 PMD:Page Middle Derectory,页中间目录,是第三级页表。
 PTE:Page Table Entry,页面表,最后一级页表,指向物理页面。
 可以通过数据结构mm_struct访问PGD找到物理页面,如图4-8,根据页表寻找物理地址的流程见4-9。
 
图  Linux采用的4级页面
 

 简化的转换代码如下:
 static int vir2phy(unsigned long va) 
 {     
  struct task_struct *pcb_tmp;     
  pcb_tmp = current;     
  pgd_tmp = pgd_offset(pcb_tmp->mm,va);     
  pud_tmp = pud_offset(pgd_tmp,va);     
  pmd_tmp = pmd_offset(pud_tmp,va);     
  pte_tmp = pte_offset_kernel(pmd_tmp,va);      
  pa = (pte_val(*pte_tmp) & PAGE_MASK) |(va & ~PAGE_MASK);     
  return pa; 
 }

pgd_offset(mm, addr) 接收内存描述符地址mm和线性地址addr作为参数。这个宏产生地址addr在页全局目录中相应表项的线性地址;
通过内存描述符mm内的一个指针可以找到这个页全局目录。

pud_offset(pgd, addr) 参数为指向页全局目录项的指针pgd和线性地址addr。这个宏产生页上级目录中目录项addr对应的线性地址。在两级或三级分页系统中,该宏产生pgd,即一个页全局目录项的地址。

pmd_offset(pud, addr) 接收指向页上级目录项的指针pud和线性地址addr作为参数。这个宏产生目录项addr在页中间目录中的偏移地址。在两级或三级分页系统中,它产生pud,即页全局目录项的地址。

pte_offset_kernel(dir, addr) 线性地址addr在页中间目录dir中有一个对应的项,该宏就产生这个对应项,即页表的线性地址。另外,该宏只在主内核页表上使用。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
假设我们有一个 32 位的虚拟地址空间和 4KB 的页大小,同时假设我们的页表是以二级页表的形式组织的,每个页表项大小为 4 字节,那么我们可以按照以下步骤将一个虚拟地址转换物理地址: 1. 将 32 位的虚拟地址划分为三个部分: - 前 10 位为页目录项索引(Page Directory Index),用于查找页目录表中的对应页表项。 - 接下来的 10 位为页表项索引(Page Table Index),用于在页表中查找对应的页框号。 - 最后的 12 位为页内偏移量(Page Offset),表示该地址在页内的偏移量。 假设我们要将虚拟地址 0x12345678 转换为物理地址,那么它的页目录项索引为 0x1234,页表项索引为 0x567,页内偏移量为 0x8。 2. 根据页目录项索引找到页目录表中的对应页表项,并从中取出页表的物理地址。 假设页目录表的起始物理地址为 0x80000000,每个页表项大小为 4 字节,那么我们可以通过以下公式计算出页目录项的物理地址: ``` page_directory_entry_address = 0x80000000 + (page_directory_index * 4) ``` 在这里,页目录项索引为 0x1234,所以页目录项的物理地址为 0x800049D0,从中取出页表的物理地址。 3. 根据页表项索引找到页表中的对应页框号。 假设页表的起始物理地址为 0x90000000,每个页表项大小为 4 字节,那么我们可以通过以下公式计算出页表项的物理地址: ``` page_table_entry_address = page_table_address + (page_table_index * 4) ``` 在这里,页表的物理地址为 0x90001234,页表项索引为 0x567,所以页表项的物理地址为 0x90002B5C,从中取出对应的页框号。 4. 将页框号与页内偏移量组合成物理地址。 假设页大小为 4KB,那么该页的起始地址为 0x10000 * 页框号,因此,我们可以通过以下公式计算出物理地址: ``` physical_address = (page_frame_number * 0x1000) + page_offset ``` 在这里,页框号为 0x123,所以该页的起始地址为 0x123000,页内偏移量为 0x8,因此物理地址为 0x123008。 通过以上步骤,我们将虚拟地址 0x12345678 转换为物理地址 0x123008。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值