趣谈 Linux 操作系统
刘超
前网易杭州研究院云计算技术部首席架构师
84364 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 72 讲
趣谈 Linux 操作系统
15
15
1.0x
00:00/00:00
登录|注册

26 | 内核态内存映射:如何找到正确的会议室?

前面讲用户态内存映射机制的时候,我们已经多次引申出了内核的映射机制,但是咱们都暂时放了放,这一节我们就来详细解析一下,让你彻底搞懂它。
首先,你要知道,内核态的内存映射机制,主要包含以下几个部分:
内核态内存映射函数 vmalloc、kmap_atomic 是如何工作的;
内核态页表是放在哪里的,如何工作的?swapper_pg_dir 是怎么回事;
出现了内核态缺页异常应该怎么办?

内核页表

和用户态页表不同,在系统初始化的时候,我们就要创建内核页表了。
我们从内核页表的根 swapper_pg_dir 开始找线索,在 arch/x86/include/asm/pgtable_64.h 中就能找到它的定义。
extern pud_t level3_kernel_pgt[512];
extern pud_t level3_ident_pgt[512];
extern pmd_t level2_kernel_pgt[512];
extern pmd_t level2_fixmap_pgt[512];
extern pmd_t level2_ident_pgt[512];
extern pte_t level1_fixmap_pgt[512];
extern pgd_t init_top_pgt[];
#define swapper_pg_dir init_top_pgt
swapper_pg_dir 指向内核最顶级的目录 pgd,同时出现的还有几个页表目录。我们可以回忆一下,64 位系统的虚拟地址空间的布局,其中 XXX_ident_pgt 对应的是直接映射区,XXX_kernel_pgt 对应的是内核代码区,XXX_fixmap_pgt 对应的是固定映射区。
它们是在哪里初始化的呢?在汇编语言的文件里面的 arch\x86\kernel\head_64.S。这段代码比较难看懂,你只要明白它是干什么的就行了。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《趣谈 Linux 操作系统》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(26)

  • 最新
  • 精选
  • 没心没肺
    好恐怖,看到这里,是硬看了

    作者回复: 不怕不怕

    2
    17
  • ezra.xu
    内核能用c语言编写,是不是意味着用c可以直接操作物理内存,另外linux上的c语言编译器是用什么语言开发的,c语言实现了自举吗,c语言跨平台底层原理是什么,请老师答疑解惑。

    作者回复: 是因为C语言编译完了就直接是硬件能够识别的二进制,不像java,需要jvm才能运行。C语言不用自举,除了第一个开发C语言的,需要用汇编来做,后面都可以用锤子造锤子

    2
    16
  • 莫名
    👍看起来很有感觉,先讲用户态、内核态虚拟内存的管理,然后讲物理内存的管理,最后讲用户态、内核态虚拟内存与物理内存如何建立关联。

    作者回复: 赞,有感觉就好,要的就是心动

    7
  • 活的潇洒
    坚持完整的学到底,坚持完整的笔记到底 day26 学习笔记:https://www.cnblogs.com/luoahong/p/10931320.html

    作者回复: 加油

    3
  • LDxy
    操作系统是如何知道计算机上有多少物理内存的呢?

    作者回复: 初始化的时候,会检测硬件

    2
  • Mhy
    老师,看到这里我是不是可以认为在用户态使用mmap和内核态使用mmap是两码事,我们一般应用场景比如将图片内存直接映射到用户空间上访问避免多次拷贝从而提高图片加载速度,那么这个场景是发生在用户态上面,期间不需要通过内核态吗?调用系统函数触发的mmap是发生在内核态吗,比如strace ls -l

    作者回复: 不是的,mmap是系统调用,不存在内核调用他的

    1
  • Bing
    用malloc申请的内存,进程退出时,操作系统是否会释放

    作者回复: 当然会啊,虚拟内存嘛

    1
  • 栋能
    没太看懂kmalloc又是从哪里来的,是写错了么?(这个我还特意往前找了下,以为是kmmap,用于内存映射区的呢)

    作者回复: kmalloc内核空间内存申请函数。

  • 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 会被换出
    23
  • 活的潇洒
    决心从头把计算机所有的基础课程全部补上,夯实基础,一定要坚持到最后 day26笔记:https://www.cnblogs.com/luoahong/p/10931320.html
    2
    20
收起评论
显示
设置
留言
26
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部