26 | 内核态内存映射:如何找到正确的会议室?
刘超
该思维导图由 AI 生成,仅供参考
前面讲用户态内存映射机制的时候,我们已经多次引申出了内核的映射机制,但是咱们都暂时放了放,这一节我们就来详细解析一下,让你彻底搞懂它。
首先,你要知道,内核态的内存映射机制,主要包含以下几个部分:
内核态内存映射函数 vmalloc、kmap_atomic 是如何工作的;
内核态页表是放在哪里的,如何工作的?swapper_pg_dir 是怎么回事;
出现了内核态缺页异常应该怎么办?
内核页表
和用户态页表不同,在系统初始化的时候,我们就要创建内核页表了。
我们从内核页表的根 swapper_pg_dir 开始找线索,在 arch/x86/include/asm/pgtable_64.h 中就能找到它的定义。
swapper_pg_dir 指向内核最顶级的目录 pgd,同时出现的还有几个页表目录。我们可以回忆一下,64 位系统的虚拟地址空间的布局,其中 XXX_ident_pgt 对应的是直接映射区,XXX_kernel_pgt 对应的是内核代码区,XXX_fixmap_pgt 对应的是固定映射区。
它们是在哪里初始化的呢?在汇编语言的文件里面的 arch\x86\kernel\head_64.S。这段代码比较难看懂,你只要明白它是干什么的就行了。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
本文深入解析了内核态的内存映射机制,重点讨论了内核页表的创建和初始化过程。文章首先介绍了内核页表的根swapper_pg_dir及其相关页表目录的定义和初始化过程,然后详细讲解了内核页表的初始化,包括对物理内存的映射和虚拟地址与物理地址的转换。作者强调了内核页表的重要性,以及为满足CPU和内存硬件需求而进行的复杂初始化过程。此外,文章还探讨了vmalloc和kmap_atomic的原理,以及内核态的缺页异常处理机制。通过对内核态内存映射机制的详细解析,读者能够全面了解内核页表的创建和初始化过程,以及其在系统启动时的重要作用。整体而言,本文内容涵盖了内核内存管理的关键方面,为读者提供了深入的技术视角和理解。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《趣谈 Linux 操作系统》,新⼈⾸单¥68
《趣谈 Linux 操作系统》,新⼈⾸单¥68
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(26)
- 最新
- 精选
- 没心没肺好恐怖,看到这里,是硬看了
作者回复: 不怕不怕
2019-07-05217 - ezra.xu内核能用c语言编写,是不是意味着用c可以直接操作物理内存,另外linux上的c语言编译器是用什么语言开发的,c语言实现了自举吗,c语言跨平台底层原理是什么,请老师答疑解惑。
作者回复: 是因为C语言编译完了就直接是硬件能够识别的二进制,不像java,需要jvm才能运行。C语言不用自举,除了第一个开发C语言的,需要用汇编来做,后面都可以用锤子造锤子
2019-05-27216 - 莫名👍看起来很有感觉,先讲用户态、内核态虚拟内存的管理,然后讲物理内存的管理,最后讲用户态、内核态虚拟内存与物理内存如何建立关联。
作者回复: 赞,有感觉就好,要的就是心动
2019-07-187 - 活的潇洒坚持完整的学到底,坚持完整的笔记到底 day26 学习笔记:https://www.cnblogs.com/luoahong/p/10931320.html
作者回复: 加油
2019-05-273 - LDxy操作系统是如何知道计算机上有多少物理内存的呢?
作者回复: 初始化的时候,会检测硬件
2019-06-022 - Mhy老师,看到这里我是不是可以认为在用户态使用mmap和内核态使用mmap是两码事,我们一般应用场景比如将图片内存直接映射到用户空间上访问避免多次拷贝从而提高图片加载速度,那么这个场景是发生在用户态上面,期间不需要通过内核态吗?调用系统函数触发的mmap是发生在内核态吗,比如strace ls -l
作者回复: 不是的,mmap是系统调用,不存在内核调用他的
2020-05-081 - Bing用malloc申请的内存,进程退出时,操作系统是否会释放
作者回复: 当然会啊,虚拟内存嘛
2019-08-151 - 栋能没太看懂kmalloc又是从哪里来的,是写错了么?(这个我还特意往前找了下,以为是kmmap,用于内存映射区的呢)
作者回复: kmalloc内核空间内存申请函数。
2019-07-25 - why- 涉及三块内容: - 内存映射函数 vmalloc, kmap_atomic - 内核态页表存放位置和工作流程 - 内核态缺页异常处理 - 内核态页表, 系统初始化时就创建 - swapper_pg_dir 指向内核顶级页目录 pgd - xxx_ident/kernel/fixmap_pgt 分别是直接映射/内核代码/固定映射的 xxx 级页表目录 - 创建内核态页表 - swapper_pg_dir 指向 init_top_pgt, 是 ELF 文件的全局变量, 因此再内存管理初始化之间就存在 - init_top_pgt 先初始化了三项 - 第一项指向 level3_ident_pgt (内核代码段的某个虚拟地址) 减去 __START_KERNEL_MAP (内核代码起始虚拟地址) 得到实际物理地址 - 第二项也是指向 level3_ident_pgt - 第三项指向 level3_kernel_pgt 内核代码区 - 初始化各页表项, 指向下一集目录 - 页表覆盖范围较小, 内核代码 512MB, 直接映射区 1GB - 内核态也定义 mm_struct 指向 swapper_pg_dir - 初始化内核态页表, start_kernel→ setup_arch - load_cr3(swapper_pg_dir) 并刷新 TLB - 调用 init_mem_mapping→kernel_physical_mapping_init, 用 __va 将物理地址映射到虚拟地址, 再创建映射页表项 - CPU 在保护模式下访问虚拟地址都必须通过 cr3, 系统只能照做 - 在 load_cr3 之前, 通过 early_top_pgt 完成映射 - vmalloc 和 kmap_atomic - 内核的虚拟地址空间 vmalloc 区域用于映射 - kmap_atomic 临时映射 - 32 位, 调用 set_pte 通过内核页表临时映射 - 64 位, 调用 page_address→lowmem_page_address 进行映射 - 内核态缺页异常 - kmap_atomic 直接创建页表进行映射 - vmalloc 只分配内核虚拟地址, 访问时触发缺页中断, 调用 do_page_fault→vmalloc_fault 用于关联内核页表项 - kmem_cache 和 kmalloc 用于保存内核数据结构, 不会被换出; 而内核 vmalloc 会被换出2019-05-2723
- 活的潇洒决心从头把计算机所有的基础课程全部补上,夯实基础,一定要坚持到最后 day26笔记:https://www.cnblogs.com/luoahong/p/10931320.html2019-05-29220
收起评论