虚拟地址转换为物理地址
2014-07-24 19:10
260 查看
应用程序只能提供一个虚拟地址,也可以通过如下方法获取物理地址,当然得调用驱动。
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级页面
![](http://hiphotos.baidu.com/aokikyon/pic/item/cd92ecf9540b650a242df276.jpg)
简化的转换代码如下:
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中有一个对应的项,该宏就产生这个对应项,即页表的线性地址。另外,该宏只在主内核页表上使用。
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级页面
![](http://hiphotos.baidu.com/aokikyon/pic/item/cd92ecf9540b650a242df276.jpg)
简化的转换代码如下:
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中有一个对应的项,该宏就产生这个对应项,即页表的线性地址。另外,该宏只在主内核页表上使用。
相关文章推荐
- Linux_虚拟地址、线性地址和物理地址的转换
- 利用/proc/pid/pagemap将虚拟地址转换为物理地址
- 启用PAE机制下虚拟地址到物理地址的转换
- Linux 内核 虚拟地址 物理地址 转换
- 【解答】关于内核中没开MMU之前的虚拟地址物理地址转换问题
- 【Linux内存管理】虚拟地址、逻辑地址、线性地址、物理地址之间的转换
- 【软件安全】PAE下虚拟地址到物理地址的转换
- 在用户态进行虚拟空间地址向物理空间地址的转换
- 用户空间的虚拟地址如何转换得到实际的物理地址
- 启用PAE机制下虚拟地址到物理地址的转换
- 物理地址转换成虚拟地址MmMapIoSpace
- 虚拟地址、线性地址和物理地址的转换
- 虚拟地址转换成物理地址
- Linux 内核虚拟地址到物理地址转换讨论
- [课上练习]手工将虚拟地址转换为物理地址
- 将虚拟地址转换成物理地址
- [Linux内存管理-分页机制]—把一个虚拟地址转换为物理地址
- windows平台下虚拟地址转换到物理地址
- Linux_虚拟地址、线性地址和物理地址的转换
- ARM Android内核虚拟地址到物理地址的转换实例 (ARM Android kernel virtual address to physical address)