Linux核心概念详解
  • 0. Linux核心概念详解
  • 1. 调试环境
  • 2. Linux 调度器
    • 2.1 任务
    • 2.2 核心概念
      • 2.2.1 核心概念 - 调度实体
      • 2.2.2 核心概念 - 调度类
      • 2.2.3 核心概念 - 调度策略
      • 2.2.4 核心概念 - 运行队列
      • 2.2.5 核心概念 - 优先级
    • 2.3 演进历史
      • 2.3.1 O(n)调度器 - 调度逻辑
      • 2.3.2 O(n)调度器 - 时间分配
      • 2.3.3 O(n)调度器 - 调度时机
      • 2.3.4 O(1)调度器 - 简介
      • 2.3.5 O(1)调度器 - 调度逻辑
      • 2.3.6 O(1)调度器 - 时间分配
      • 2.3.7 RSDL
      • 2.3.8 CFS
    • 2.4 DL调度器
      • 2.4.1 DL调度器 - 调度算法
      • 2.4.2 DL调度器 -核心代码
    • 2.5 RT调度器
    • 2.6 CFS
      • 2.6.1 公平性
      • 2.6.2 调度逻辑
      • 2.6.2.1 调度逻辑 - 数据结构
      • 2.6.2.2 调度逻辑 - vruntime
      • 2.6.2.3 调度逻辑 - 调度周期
      • 2.6.2.4 调度逻辑 - 调度节拍
      • 2.6.2.5 调度逻辑 - 任务抢占
      • 2.6.2.6 调度逻辑 - 调度时机
      • 2.6.3 组调度
      • 2.6.3.1 组调度 - 数据结构
      • 2.6.3.2 组调度 - 调度逻辑
      • 2.6.3.3 组调度 - 时间分配
      • 2.6.3.4 组调度 - 任务组权重
      • 2.6.4 带宽控制
      • 2.6.4.1 带宽控制 - 数据结构
      • 2.6.4.2 带宽控制 - 带宽时间
      • 2.6.4.3 带宽控制 - 挂起与解挂
      • 2.6.4.3 带宽控制 - 定时器
    • 2.7 负载追踪
      • 2.7.1 负载追踪 - 简介
      • 2.7.2 负载追踪 - 数据结构
      • 2.7.3 负载追踪 - 计算负载
      • 2.7.4 负载追踪 - 更新负载
    • 2.8 负载均衡
      • 2.8.1 简介
      • 2.8.2 CPU的拓扑结构
      • 2.8.3 数据结构
      • 2.8.4 算法思路
      • 2.8.5 触发时机
      • 2.8.6 总结
  • 3. LINUX 内存管理
    • 3.1 寻址模式
      • 3.1.1 地址
      • 3.1.2 地址转换
      • 3.1.3 Linux的地址空间
    • 3.2 物理内存
      • 3.2.1 数据结构
      • 3.2.2 初始化
      • 3.2.3 物理内存模型
      • 3.2.4 Buddy System(伙伴系统)
      • 3.2.5 SLAB/SLUB/SLOB
Powered by GitBook
On this page

Was this helpful?

  1. 3. LINUX 内存管理
  2. 3.2 物理内存

3.2.2 初始化

Previous3.2.1 数据结构Next3.2.3 物理内存模型

Last updated 3 years ago

Was this helpful?

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

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

  1. 探测物理内存 - E820 OS要管理内存,首先需要知道系统有多少可用的物理内存,该部分信息通过一个叫着的机制来获取,在系统加电时, 通过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 系统来提供对象缓存机制。

E820
BIOS
https://biscuitos.github.io/blog/MMU-E820/
https://wiki.osdev.org/Detecting_Memory_(x86)#BIOS_Function:_INT_0x15.2C_EAX_.3D_0xE820
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/