内核管理实战之虚地址转换为物理地址
来源:互联网 发布:python io模块 编辑:程序博客网 时间:2024/05/17 21:06
CPU只能访问虚拟内存,而实际的数据都存放在物理内存上面,
这就需要将虚拟内存映射到物理内存上面去,然后在物理内存上获取数
据传送到CPU中进行运算,而这个地址的映射就通过页表来完成的。
---------------------------------------------------------------------------------
一,linux内核的四级页表。
内核为什么要设计四级页表呢?主要是为了支持多种硬件平台,
---------------------------------------------------------------------------------
一,linux内核的四级页表。
内核为什么要设计四级页表呢?主要是为了支持多种硬件平台,
各种CPU提供的硬件支持不一样,还有要支持64位机。内核的4级页表可
以退化为3级页表,还可以退化到2级页表。四级页表也就是把一个虚拟
地址分为了5部分,分别是PGD,PUD,PMD,PTE,offset
示意图如下:
------------------------------------------------------------------------------
二,实战,将一个用vmalloc开辟的地址映射为物理地址。
模块运行结果:(环境:linux.2.6.36,intel 32位系统)
可以看出pud和pmd的偏移量均为0,说明在这儿就只使用了二级页表,
示意图如下:
------------------------------------------------------------------------------
二,实战,将一个用vmalloc开辟的地址映射为物理地址。
- static unsigned long vaddr_to_paddr(unsigned long va)
- {
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte;
- unsigned long paddr;
- unsigned long page_addr;
- unsigned long page_offset;
- pgd = pgd_offset(current->mm,va);
- printk("pgd_val = 0x%lx\n",pgd_val(*pgd));
- printk("pgd_index = %lu\n",pgd_index(va));
- if (pgd_none(*pgd)) {
- printk("not mapped in pgd!\n");
- return -1;
- }
- pud = pud_offset(pgd,va);
- printk("pud_val = 0x%lx\n",pud_val(*pud));
- printk("pud_index = %lu\n",my_pud_index(va));
- if (pud_none(*pud)) {
- printk("not mapped in pud!\n");
- return -1;
- }
- pmd = pmd_offset(pud,va);
- printk("pmd_val = 0x%lx\n",pmd_val(*pmd));
- printk("pmd_index = %lu\n",pmd_index(va));
- if (pmd_none(*pmd)) {
- printk("not mapped in pmd!\n");
- return -1;
- }
- pte = pte_offset_kernel(pmd,va);
- printk("pte_val = 0x%lx\n",pte_val(*pte));
- printk("pte_index = %lu\n",pte_index(va));
- if (pte_none(*pte)) {
- printk("not mapped in pte!\n");
- return -1;
- }
-
- page_addr = pte_val(*pte) & PAGE_MASK;
- page_offset = va & ~PAGE_MASK;
- paddr = page_addr | page_offset;
- printk("vaddr = %lx,paddr = %lx\n",va,paddr);
- printk("page_addr = %lx\n",page_addr);
-
- return paddr;
- }
- [263298.365202] pgd_val = 0x5e18067
- [263298.365207] pgd_index = 995
- [263298.365210] pud_val = 0x5e18067
- [263298.365213] pud_index = 0
- [263298.365216] pmd_val = 0x5e18067
- [263298.365218] pmd_index = 0
- [263298.365221] pte_val = 0x63c0163
- [263298.365223] pte_index = 127
- [263298.365226] vaddr = f8c7f000,paddr = 63c0000
- [263298.365229] page_addr = 63c0000
将pud和pmd都“折叠”起来了。代码的过程完全可以由上面的图解释。
-----------------------------------------------------------------------------------------
三,模块完整代码
vaddr_to_paddr.rar
------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
三,模块完整代码
vaddr_to_paddr.rar
------------------------------------------------------------------------------------------
0 0
- 内核管理实战之虚地址转换为物理地址
- 储存管理 与 虚拟地址如何转换为物理地址
- 虚拟地址转换为物理地址
- 逻辑地址转换为物理地址
- 进程地址空间地址转换为物理地址
- Linux 内核 虚拟地址 物理地址 转换
- Linux 内核 虚拟地址 物理地址 转换
- Linux开发心得总结8 - 虚地址转换为物理地址
- 初试将虚拟地址转换为物理地址
- windbg:虚拟地址转换为物理地址
- [Linux内存管理-分页机制]—把一个虚拟地址转换为物理地址
- Linux内核层虚拟地址和物理地址转换函数
- Linux 内核空间虚拟地址和物理地址相互转换
- Linux 内核虚拟地址到物理地址转换讨论
- linux内存管理-虚拟地址转换成物理地址的过程
- 物理地址通过什么协议转换为ip地址
- [课上练习]手工将虚拟地址转换为物理地址
- ARM Linux虚拟地址转换为内存物理地址
- "Fragment"-Android面试必问"精华技能点"汇总
- 皮划艇找瓶子--------阿里巴巴2015校招研发在线
- Summer day 1
- 提示框&对话框
- iostat命令使用指南
- 内核管理实战之虚地址转换为物理地址
- android app 默认的crash处理流程 (FATAL EXCEPTION)
- 自定义控件
- Bitmap
- 【js学习笔记-036】--属性的特性
- Opencv图像识别从零到精通(3)———单图像显示和多图像显示
- Codeforces Round #337 (Div. 2) 610A(水)
- 取书
- FastDFS客户端协议