# 3.2.2 初始化

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

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

1. 探测物理内存 - E820 OS要管理内存，首先需要知道系统有多少可用的物理内存，该部分信息通过一个叫着[E820](https://en.wikipedia.org/wiki/E820)的机制来获取，在系统加电时， [BIOS](https://en.wikipedia.org/wiki/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的详细实现可以参考如下资料：

   * <https://biscuitos.github.io/blog/MMU-E820/>
   * <https://wiki.osdev.org/Detecting_Memory_(x86)#BIOS_Function:_INT_0x15.2C_EAX_.3D_0xE820>
2. 初始化时内存管理 - bootmem/memblock 在系统启动阶段，Buddy System并没有初始化，系统使用的是专门的内存管理器来管理物理内存的分配与释放，Linux 早期使用的是 bootmem, 后来逐渐演化成了现在使用的 memblock. 内核中与 memblock 相关的代码集中在如下文件中：

   * include/linux/memblock.h
   * mm/memblock.c

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

   * <https://lwn.net/Articles/761215/>
   * <https://www.kernel.org/doc/gorman/html/understand/understand008.html>
   * <https://www.kernel.org/doc/html/v4.19/core-api/boot-time-mm.html>
   * <https://biscuitos.github.io/blog/HISTORY-bootmem/>
   * <https://biscuitos.github.io/blog/MMU-ARM32-MEMBLOCK-index/>
3. 运行时内存管理 - Buddy System 系统正常运行起来之后，负责物理内存页面的分配与释放的子系统叫 Buddy System, 我们将在后面详细介绍；另外内核还通过 slab/slob/slub 系统来提供对象缓存机制。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://s3.shizhz.me/linux-mm/3.2-wu-li-nei-cun/3.2.2-chu-shi-hua.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
