`
tomhibolu
  • 浏览: 1431197 次
文章分类
社区版块
存档分类
最新评论

kernel hacker修炼之道之内存管理-分页

 
阅读更多

浅析linux内核内存管理之分页

作者:李万鹏


硬件中的分页


硬件中的分页分常规分页和扩展分页:



常规分页,32位的线性地址被分为3个域:


  • Directory(目录) 最高10位
  • Table(页表) 中间10位
  • Offset(偏移量) 最低12位

扩展分页,32位的线性地址被分为2个域:

  • Directory 最高10位
  • Offset 其余22位

扩展分页和正常分页的页目录项基本相同,除了:

  • Page Size标志必须被设置
  • 20位物理地址字段只有最高10位是有意义的。这是因为每一个物理地址都是在以4MB为边界的地方开始的,故这个地址的最低22位为0

页目录项:

页表项:


Linux中的分页

从linux 2.6.11开始采用了四级分页模型:

  • 页全局目录(Page Global Directory) —— ——>PDT(PAE未开启)或PDPT(PAE开启)
  • 页上级目录(Page Upper Directory)
  • 页中间目录(Page Middle Directory) —— ——>PDT(PAE未开启)
  • 页表(Page Table) —— —— —— —— ——>PT

PTRS_PER_PTE,PTRS_PER_PMD,PTRS_PER_PUD以及PTRS_PER_PGD
用于计算页表,页中间目录,页上级目录和页全局目录表中表项的个数。当PAE被禁止时,它们产生的值分别为1024,1,1和1024。当PAE被激活时,产生的值分别为512,512,1和4。

注意:PAE关闭时,PGD就是PDT,此时不用PUD,PMD。虽然它们两个在线性地址中,但长度为0,2^0=1,也就是说,它们都是有一个数组元素的数组。当PAE启动时,PGD指示四个PDPT entry中的哪一个, 不使用PUD。

那么使用分页有什么好处呢?
就拿二级分页来说吧,如果不用二级分页,用一级,那么4GB需要4MB物理内存存放entry,一个页4KB,entry4B。如果用两级分页,2^10*2^10*4KB=4GB。所以需要两个页就行,每个页1024 entry。4KB+4KB=8KB。实际上,用不上8KB的,并不是所有entry都是存在的,正如下边说的那个函数,有的entry会为空,这样又节省很多空间。所以实际页表与页目录占用的空间小于8KB,多合算阿。

页表处理

pte_t,pmd_t,pud_t和pgd_t分别描述页表项,页中间目录项,页上级目录和页全局目录的格式。当PAE被激活的时他们都是64位的数据类型,否则都是32位数据类型。pgprot_t是另一个64位(PAE激活时)或32位(PAE禁用时)的数据类型,它表示与一个单独表项相关的保护标志。
五个类型转换宏(__pte,__pmd,__pud,__pgd和__pgprot)把一个无符号整数转换成所需的类型。另外的五个类型转换宏(pte_val,pmd_val,pud_val,pgd_val和pgprot_val)执行相反的转换,即把上面提到的四种特殊的类型转换成一个无符号整数。

内核还提供许多宏用于读取或修改页表项:
  • 如果相应的表项值为0,那么,宏pte_none,pmd_none,pud_none和pgd_none产生的值为1,否则产生的值为0。
  • 宏pte_clear,pmd_clear,pud_clear和pgd_clear清除相应页表一个表项,由此禁止进程使用由该页表项映射的线性地址。ptep_get_and_clear()函数清除一个页表项并返回前一个值。
  • set_pte,set_pmd,set_pud和set_pgd向一个页表项中写入指定的值。
  • 如果a和b两个表项页表项指向同一页并且指定相同的访问优先级,那么pte_same(a,b)返回1,否则返回0。
  • 如果页中间目录指向一个大型页(2MB或4MB),那么pmd_large(e)返回1,否则返回0.

如果一个页表项的Present标志或者Page Size标志等于1,则pte_present宏产生的值为1,否则为0。前面讲过页表项的Page Size标志对微处理器的分页单元来讲没有意义,然而,对于当前在主存中却没有读,写或执行权限的页,内核将其Present和Page Size分别标记为0和1。这样,任何试图对此类页的访问都会引起一个缺页异常,因为页的Present标志被清0,而内核可以通过检查Page Size的值来检查到产生异常并不是因为缺页。

读页标志的函数:


设置页标志的函数:


对页表项操作的宏:

这里需要注意的是,如果是32位未开启PAE,则pud_offset,pmd_offset返回的仍是pgd;如果是32位开启PAE,则pud_offset返回的是pgd。pgd_offset,pud_offset,pmd_offset,pte_offset_map等返回的都是线性地址,比如,pmd_offset返回的pmd中相应表项的线性地址,*pmd_offset(pud,addr)才是表项中的值,即PT的地址。还有一个要注意的地方就是pte_offset_map,如果页表被保存在高端内存,那么就建立一个临时内核映射,这样就可以编辑页表了,等编辑完了,在解除临时内核映射。举个例子,do_anonymous_page()函数中有这么一段:

解释一下:
调用handle_mm_fault分配一个新的页框,分配了pud,pmd,实际返回的都是pgd中的表项(如果是x86 32,未开启PAE),调用pte_alloc_map,如果pgd中的表项为空,则新分配一个页表,如果是HIGHPTE就从highmem分,如果不空并且是HIGHPTE则调用kmap_atomic将这个页表映射到临时内核映射区的一个窗口KM_PTE0,这样内核就可以编辑这个页表了,即设置相应表项。do_anonymous_page中从highmem为引起page fault的线性地址分配页框。第一次pte_unmap之后又pte_offset_map是为了防止一旦alloc_page导致进程睡眠,临时内核映射被覆盖。然后用新分配到的页框设置页表项,临时内核很宝贵的,由于编辑完页表了,解除临时内核映射,分配页框任务完成。

页分配函数:

在x86 32位未开启PAE的时候,调用pud_alloc,pmd_alloc其实并未真正分配,上边说了,其实此时pud,pmd只有一项,目的就是在请求pud,pmd的时候返回pgd。如下边map_vm_area()中的pud_alloc,并没有真正分配。而是通过pud,pmd一一转手,目的应该是与64位兼容。


写了一个测试程序:

测试结果:

注意判断是否是大页,好多人没有考虑这个地方,导致各种诡异的问题。




分享到:
评论

相关推荐

    Linux常见驱动源码分析(kernel hacker修炼之道全集)--李万鹏

    Linux常见驱动源码分析(kernel hacker修炼之道)--李万鹏 李万鹏 IBM Linux Technology Center kernel team 驱动资料清单内容如下: Linux设备模型(中)之上层容器.pdf Linux设备模型(上)之底层模型.pdf Linux...

    常见驱动源码分析(kernel hacker修炼之道)-李万鹏

    这本书是“Linux kernel hacker修炼之道”的一部分,通过深入剖析各种常见的驱动源码,帮助读者提升在Linux系统中的驱动开发能力。 在Linux操作系统中,驱动程序是连接硬件与内核的桥梁,它们负责管理和控制硬件...

    常见驱动源码分析(kernel hacker修炼之道)

    《常见驱动源码分析(kernel hacker修炼之道)》这本书或课程很可能深入探讨了如何理解和编写这些驱动,旨在帮助开发者提升对Linux内核和驱动编程的理解。在这个过程中,我们将会涉及到几个关键的知识点: 1. **Linux...

    linux kernel修炼之道

    如果刚刚对linux的kernel有兴趣,想了解点什么的话,请先看看此书吧,她风趣幽默的介绍了linux的发展趣事,让你开心快乐之余慢慢领会linux的魅力,让你了解学习掌握kernel的方法。其中的很多建议经过我的实践和摸索...

    Linux内核驱动笔记

    内存管理负责分配、回收内存资源,管理虚拟内存和物理内存的映射关系,并实现内存保护机制。 Linux内核支持多种文件系统,例如ext2、fat、isofs等。虚拟文件系统(VFS)是Linux内核中的一个重要概念,它为不同文件...

    hacker成长之道

    有关hacker 的文章和资料分享给大家

    processhacker-2.39-bin

    ProcessHacker是一款强大的系统信息工具,它提供了进程管理、服务管理、硬件监控、内存查看等多种功能,深受系统...通过下载并使用"processhacker-2.39-bin"压缩包,你将能够亲身体验这些功能并提升你的系统管理技能。

    x64_processhacker_源码

    Process Hacker是一款开源、免费且功能强大的系统信息工具,它允许用户查看并管理正在运行的进程、服务、线程以及内存等系统资源。 【描述】"Process Hacker 1.1 PH1" 提示我们这是Process Hacker的早期版本,版本...

    进程黑客(Process Hacker)Processhacker-3.0.4132

    Process Hacker是一款针对高级用户的安全分析工具,它可以帮助研究人员检测和解决软件或进程在特定操作系统环境下遇到的问题。除此之外,它还可以检测恶意进程,并告知我们这些恶意进程想要实现的功能。 Process ...

    The-Hacker-Playbook-3-Translation-master.zip

    渗透测试教程资料

    Algorithm-HackerRank-Solutions-In-Scala.zip

    《Scala语言解构HackerRank算法挑战》 在编程领域,算法是不可或缺的一部分,它为计算机程序提供了高效、系统地解决问题的方法。Scala是一种多范式编程语言,融合了面向对象和函数式编程的特点,因其强大的表达能力...

    processhacker-2.39-bin.rar

    Process Hacker是一款强大的系统进程管理工具,并且还可以显示CPU、GPU、IO、内存等相关使用信息。 官网地址:https://processhacker.sourceforge.io/ git地址:https://github.com/processhacker/processhacker

    processhacker-2.23-setup

    Process Hacker是一款功能丰富的系统程序,比windows自带的任务管理器功能更强大。用户只要借助该程序就可以方便,快捷地查看相关进程的速度,内存,及模块等等,除此,还可以对相关的进程进行管理工作。

    Hacker 2012.

    Hacker 2012 - Final Transfer Readme =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Thank you for downloading Hacker 2012! Registration ------------------------------------ If you like the game, ...

    rails-hackernews-reddit-producthunt-clone, 黑客 news/reddit/social 链接分享网站 用 Rails 构建.zip

    rails-hackernews-reddit-producthunt-clone, 黑客 news/reddit/social 链接分享网站 用 Rails 构建 Rails 上的 Reddit-Hackernews-ProductHunt克隆演示 这是一个 readme.md的Ruby on Rails 应用程序,模仿了 Hacker...

    Resource Hacker - 版本 3.4.0

    Resource Hacker 可以被用来: 1. 查看 Win32 可执行和相关文件的资源 (*.exe, *.dll, *.cpl, *.ocx),在已编译和反编译的格式下都可以。 2. 提取 (保存) 资源到文件 (*.res) 格式,作为二进制,或作为反编过的译...

    processhacker-2.39-src.rar

    Process Hacker是一款强大的系统进程管理工具,开源,并且还可以显示CPU、GPU、IO、内存等相关使用信息。 官网地址:https://processhacker.sourceforge.io/ git地址:...

Global site tag (gtag.js) - Google Analytics