3.2.2 初始化

内存管理模块本身也需要使用内存,例如页表、page、zone、node等数据结构的创建过程本身就需要分配内存,但此时系统的内存管理模块还没有完成初始化,又如何完成内存分配呢?这是一个鸡生蛋、蛋生鸡的问题。内存的初始化流程就是用来解决该问题的,本节我们简单介绍一下该议题,但这部分内容对我们理解内存管理模块的设计思想帮助不大,因此不做深入讲解,我们会给出一些相关的思路、涉及到的代码及参考资料,有兴趣的同学可以自行探索。

从总体思路上来讲,内存的初始化流程可以归纳为如下几个阶段:

  1. 探测物理内存 - E820 OS要管理内存,首先需要知道系统有多少可用的物理内存,该部分信息通过一个叫着E820的机制来获取,在系统加电时, BIOS通过E820这种方式获取到物理内存的大小与布局信息,以供后续的 boot loader 和操作系统使用。

    内和中涉及到E820 的文件有:

    • arch/x86/include/asm/e820/types.h

    • arch/x86/include/asm/e820/api.h

    • arch/x86/kernel/e820.c

    E820探测到的物理内存信息会打印在启动日志中,可以通过命令 dmesg | grep 'e820' 查看。有关E820的详细实现可以参考如下资料:

  2. 初始化时内存管理 - bootmem/memblock 在系统启动阶段,Buddy System并没有初始化,系统使用的是专门的内存管理器来管理物理内存的分配与释放,Linux 早期使用的是 bootmem, 后来逐渐演化成了现在使用的 memblock. 内核中与 memblock 相关的代码集中在如下文件中:

    • include/linux/memblock.h

    • mm/memblock.c

    内存的 boot allocator 的实现逻辑并不会对系统正常运行时的内存管理有太大影响,因此我们在这里不对其做深入讨论,感兴趣的读者可以参见如下资料:

  3. 运行时内存管理 - Buddy System 系统正常运行起来之后,负责物理内存页面的分配与释放的子系统叫 Buddy System, 我们将在后面详细介绍;另外内核还通过 slab/slob/slub 系统来提供对象缓存机制。

Last updated