0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

解析Linux内核页表管理中那些鲜为人知的秘密

Linux阅码场 来源:Linux内核远航者 作者:Linux内核远航者 2021-06-11 16:32 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

1.开场白

环境:

处理器架构:arm64

内核源码:linux-5.11

ubuntu版本:20.04.1

代码阅读工具:vim+ctags+cscope

通用操作系统,通常都会开启mmu来支持虚拟内存管理,而页表管理是在虚拟内存管理中尤为重要,本文主要以回答几个页表管理中关键性问题来解析Linux内核页表管理,看一看页表管理中那些鲜为人知的秘密。

2.页表的作用是什么?

1)地址转换

将虚拟地址转换为物理地址

2)权限管理

管理cpu对物理页的访问,如读写执行权限

3)隔离地址空间

隔离各个进程的地址空间,使其互不影响,提供系统的安全性

打开mmu后,对没有页表映射的虚拟内存访问或者有页表映射但是没有访问权限都会发生处理器异常,内核选择杀死进程或者panic;通过页表给一段内存设置用户态不可访问, 这样可以做到用户态的用户进程不能访问内核地址空间的内容;而由于用户进程各有一套自己的页表,所以彼此看不到对方的地址空间,更别提访问,造成每个进程都认为自己拥有所有虚拟内存的错觉;通过页表给一段内存设置只读属性,那么就不容许修改这段内存内容,从而保护了这段内存不被改写;对应用户进程地址空间映射的物理内存,内核可以很方便的进行页面迁移和页面交换,而对使用虚拟地址的用户进程来说是透明的;通过页表,很容易实现内存共享,使得一份共享库很多进程都可以映射到自己地址空间使用;通过页表,可以小内存加载大应用程序运行,在运行时按需加载和映射。..

3.页表的存放在哪?

页表存放在物理内存中,打开mmu之后,如果需要修改页表,需要将页表所在的物理地址映射到虚拟地址才能访问页表(如内核初始化后会将物理内存线性映射,这样通过物理地址和虚拟地址的偏移就可以获得页表物理地址对应的虚拟地址)。

4. 页表项中存放是虚是实?

页表基地址寄存器和各级页表项中存放的都是物理地址,而不是虚拟地址。

5. 开启mmu后地址转换过程?

虚拟地址转换物理地址的过程:打开mmu后,cpu访问的都是虚拟地址,当cpu访问一个虚拟地址的时候,会通过cpu内部的mmu来查询物理地址,mmu首先通过虚拟地址在tlb中查找,如果找到相应表项,直接获得物理地址;如果tlb没有找到,就会通过虚拟地址从页表基地址寄存器保存的页表基地址开始查询多级页表,最终查询到找到相应表项,会将表项缓存到tlb中,然后从表项中获得物理地址。

6. Linux内核为何使用多级页表?

1)使用一级页表结构优劣:

优势:

只需要2次访问内存(一次访问页表,一次访问数据),效率高,实现简单

劣势:

需要连续的大块内存存放每个进程的页表(如32位系统每个进程需要4M页表),浪费内存,虚拟内存越大页表越大,内存碎片化的时候很难分配到连续大块内存,大多数虚拟内存并没有使用。

2)使用多级页表结构优劣:

优势:

1.节省内存

2.可以按需分配各级页表

3.可以离散存储页表

劣势:

需要遍历多级页表,需要多次访问内存,实现复杂度高点

3)Linux内核综合考虑:

典型的以时间换空间,可以将各级页表放到物理内存的任何地方,无论是硬件遍历还是内核遍历,比一级页表更复杂,但是为了节省内存,内核选择多级页表结构。

7.减小多级页表遍历的优化?

1)mmu中添加tlb

来缓存最近访问的页表表项,根据程序的时间和空间的局部性原理,tlb能有很高的命中率。

2)使用巨型页

减少访存次数(如使用1G或2M巨型页),可以减少tlb miss和缺页异常。

8. 硬件做了哪些事情?

遍历页表,将va转换为pa,页面权限管理

涉及到的硬件为:

mmu

->功能:查询tlb或者遍历页表

tlb

->功能:缓存最近转换的页表条目

页表基地址寄存器 如ttbr0_el1 ttbr1_el1

->功能:存放页表基地址(物理地址)作为mmu遍历多级页表的起点

mmu进行多级页表遍历时当发现虚拟地址的最高bit为1时使用 ttbr1_el1作为遍历起点,最高bit为0时使用 ttbr0_el1作为遍历起点。

9. 软件做了哪些事情?

1)应用程序

访问虚拟内存即可如执行指令、读写内存, 没有权限管理页表

不管虚拟内存如何转换为物理内存,对应用来说透明。

2)Linux内核

填写页表,将页表基地址告诉mmu

内核初始化建立内核页表,实现缺页异常等机制为用户任务按需分配并映射页表。

当然,内核也可以遍历页表,如缺页异常时遍历进程页表。

10. 内核中涉及到的页表基地址?

内核:

idmap_pg_dir 恒等映射页表(va=pa 映射2M)

init_pg_dir 粗粒度内核页表

swapper_pg_dir 主内核页表

用户:

tsk->mm->pgd用户进程fork的时候分配私有的pgd页,用于保存pgd表项(仅仅分配了第一级页表)。

11. 页表填写/切换时机

1)内核页表填充

内核初始化过程:

物理地址 -> 恒等映射(建立恒等映射页表和粗粒度内核页表) ->打开mmu -> paging_init(建立细粒度的内核页表和内存线性映射) -> 。..

恒等映射阶段:

将恒等映射页表idmap_pg_dir 地址保存到ttbr0_el1

将 粗粒度内核页表init_pg_dir 地址保存到ttbr1_el1

paging_init阶段:

将内核主页表swapper_pg_dir 地址保存到ttbr1_el1

paging_init之后丢弃idmap_pg_dir 和init_pg_dir 页表的使用。

2)用户页表填充

访问时缺页填充:

用户进程访问已经申请的虚拟内存时,发生缺页,缺页处理程序中为进程分配各级页表等物理页并建立页表映射关系。

进程切换时切换进程页表:

switch_mm的时候切换tsk->mm->pgd到ttbr0_el1以及asid 到ttbr1_el1,从而完成了进程地址空间切换。

12.页表遍历过程

下面以arm64处理器架构多级页表遍历作为结束(使用4级页表,页大小为4K):

Linux内核中 可以将页表扩展到5级,分别是页全局目录(Page Global Directory, PGD), 页4级目录(Page 4th Directory, P4D), 页上级目录(Page Upper Directory, PUD),页中间目录(Page Middle Directory, PMD),直接页表(Page Table, PT),而支持arm64的linux使用4级页表结构分别是 pgd, pud, pmd, pt ,arm64手册中将他们分别叫做L0,L1,L2,L3级转换表,所以一下使用L0-L3表示各级页表。

tlb miss时,mmu会进行多级页表遍历遍历过程如下:

1.mmu根据虚拟地址的最高位判断使用哪个页表基地址寄存器作为起点:当最高位为0时,使用ttbr0_el1作为起点(访问的是用户空间地址);当最高位为1时,使用ttbr1_el1作为起点(访问的是内核空间地址)mmu从相应的页表基地址寄存器中获得L0转换表基地址。

2.找到L0级转换表,然后从虚拟地址中获得L0索引,通过L0索引找到相应的表项(arm64中称为L0表描述符,内核中叫做PGD表项),从表项中获得L1转换表基地址。

3.找到L1级转换表,然后从虚拟地址中获得L1索引,通过L1索引找到相应的表项(arm64中称为L1表描述符,内核中叫做PUD表项),从表项中获得L2转换表基地址。

4.找到L2级转换表,然后从虚拟地址中获得L2索引,通过L2索引找到相应的表项(arm64中称为L2表描述符,内核中叫做PUD表项),从表项中获得L3转换表基地址。

5.找到L3级转换表,然后从虚拟地址中获得L3索引,通过L3索引找到页表项(arm64中称为页描述符,内核中叫做页表项)。

6.从页表项中取出物理页帧号然后加上物理地址偏移(VA[11,0])获得最终的物理地址。

原文标题:Linux内核页表管理-那些鲜为人知的秘密

文章出处:【微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内核
    +关注

    关注

    4

    文章

    1436

    浏览量

    42490
  • Linux
    +关注

    关注

    88

    文章

    11628

    浏览量

    217962

原文标题:Linux内核页表管理-那些鲜为人知的秘密

文章出处:【微信号:LinuxDev,微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Linux内核模块的加载机制

    Linux内核模块的加载过程主要包含了ELF解析、动态链接、安全验证和资源管理技术。其核心步骤包括:权限检查→ELF解析→符号重定位→依赖
    发表于 11-25 06:59

    Linux内核printk日志级别全解析:从参数解读到实操配置

    一、开篇:一个命令引出的核心问题 在 Linux 终端执行 cat /proc/sys/kernel/printk,你可能会看到这样的输出: 这串数字不是随机的,而是内核日志系统的“核心配置开关
    的头像 发表于 11-20 15:54 1248次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>内核</b>printk日志级别全<b class='flag-5'>解析</b>:从参数解读到实操配置

    deepin亮相2025Linux内核开发者大会

    11 月 1 日,第二十届中国 Linux 内核开发者大会(CLK)在深圳举办。CLK 作为国内 Linux 内核领域极具影响力的峰会,由清华大学、Intel、华为、阿里云、富士通南大
    的头像 发表于 11-05 17:59 623次阅读

    纳米级的雕刻:揭秘芯片背后鲜为人知的酸碱艺术# 半导体# 芯片#

    半导体
    华林科纳半导体设备制造
    发布于 :2025年09月02日 17:01:55

    华纳云服务器Linux系统电源管理与节能优化配置方法

    在云计算时代,Linux系统的电源管理优化成为提升云服务器能效的关键环节。本文将深入解析Linux内核的电源
    的头像 发表于 08-21 15:09 596次阅读

    Linux内核参数调优方案

    在高并发微服务环境,网络性能往往成为K8s集群的瓶颈。本文将深入探讨如何通过精细化的Linux内核参数调优,让你的K8s节点网络性能提升30%以上。
    的头像 发表于 08-06 17:50 706次阅读

    Linux网络管理的关键技术和最佳实践

    在大型互联网企业Linux网络管理是运维工程师的核心技能之一。面对海量服务器、复杂网络拓扑、高并发流量,运维人员需要掌握从基础网络配置到高级网络优化的全套技术栈。本文将结合大厂实际场景,深入
    的头像 发表于 07-09 09:53 674次阅读

    详解Linux网络管理的关键命令

    本文档概述了网络管理的关键命令,如ifconfig配置网络接口,ip管理路由,ping测试连通性,以及nmap进行安全扫描。还介绍了nslookup和dig用于域名解析,tcpdum
    的头像 发表于 07-04 11:37 619次阅读
    详解<b class='flag-5'>Linux</b>网络<b class='flag-5'>管理</b><b class='flag-5'>中</b>的关键命令

    如何配置和验证Linux内核参数

    Linux系统运维和性能优化内核参数(sysctl)的配置至关重要。合理的参数调整可以显著提升网络性能、系统稳定性及资源利用率。然而,仅仅修改参数是不够的,如何验证这些参数是否生效同样关键。
    的头像 发表于 05-29 17:40 785次阅读

    Linux权限管理基础入门

    Linux的广阔天空中,权限管理犹如一只翱翔的雄鹰,掌控着系统的安全与秩序。掌握Linux权限,不仅能让你的系统管理更加得心应手,还能有效防止未授权访问和数据泄露。本文将带你深入探索
    的头像 发表于 05-06 13:44 549次阅读
    <b class='flag-5'>Linux</b>权限<b class='flag-5'>管理</b>基础入门

    Linux内核编译失败?移动硬盘和虚拟机的那些事儿

    Linux开发,编译内核是一项常见任务,但不少开发者在移动硬盘或虚拟机环境下尝试时会遭遇失败。本文将简要探讨这些问题的成因,并介绍一些虚拟机使用技巧,帮助大家更好地应对相关问题。在移动硬盘里编译
    的头像 发表于 04-11 11:36 729次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>内核</b>编译失败?移动硬盘和虚拟机的<b class='flag-5'>那些</b>事儿

    十大鲜为人知却功能强大的机器学习模型

    本文转自:QuantML当我们谈论机器学习时,线性回归、决策树和神经网络这些常见的算法往往占据了主导地位。然而,除了这些众所周知的模型之外,还存在一些鲜为人知但功能强大的算法,它们能够以惊人的效率
    的头像 发表于 04-02 14:10 915次阅读
    十大<b class='flag-5'>鲜为人知</b>却功能强大的机器学习模型

    树莓派4 性能大比拼:标准Linux与实时Linux 4.19内核的延迟测试

    使用的是raspberrypi/linux仓库的rpi-4.19.y-rt分支。同样,在测试,我使用了实时Linux项目中的cyclictest程序。Cyclictest程序
    的头像 发表于 03-25 09:39 656次阅读
    树莓派4 性能大比拼:标准<b class='flag-5'>Linux</b>与实时<b class='flag-5'>Linux</b> 4.19<b class='flag-5'>内核</b>的延迟测试

    腾讯云内核团队修复Linux关键Bug

    Maintainer深感棘手的关键内核bug。 这一改进方案经过严格评审和测试,最终被合并进入后续的Linux LTS(长期支持)版本,标志着腾讯云在操作系统内核领域的技术实力得到了
    的头像 发表于 12-31 10:58 915次阅读

    飞凌嵌入式ElfBoard ELF 1板卡-Linux内核移植之内核简介

    及时,在遇到一些内核问题时就可以到linux官网的源码查一下是不是有相关的提交记录。获取芯片原厂的linux源码每个芯片原厂都有自己的git仓库,他们会把已经开发完成的
    发表于 12-13 09:03