内存管理篇-09伙伴系统初始化一:memblock管理

1.伙伴系统的初始化概述

硬件初始化:计算机加电后进行硬件检测。加载引导程序,将Linux内核加载到内存中。

内核初始化:内核被加载后开始初始化各个子系统。进行CPU架构相关的初始化。初始化内存控制器和其他设备驱动。

内存管理初始化:在内核初始化的过程中,会调用mm_init函数来初始化内存管理系统。mm_init函数会初始化包括伙伴系统在内的各种内存管理组件

伙伴系统初始化

  • 伙伴系统的初始化通常发生在内存管理初始化阶段,即mm_init函数执行期间。
  • 首先,初始化与伙伴系统相关的数据结构,如struct zone等。
  • 然后,将由初始内存分配器(如memblock allocator)管理的内存空间释放到伙伴系统中
  • 在初始化过程中,会对每个节点(node)建立内存分配的zone优先级列表。
  • 对于x86架构,高端内存和低端内存的伙伴系统初始化是分开进行的,一般先初始化高端内存区,再初始化低端内存区。

初始化完成

  • 完成伙伴系统的初始化后,内核就可以使用伙伴系统来管理物理内存的分配和回收

所以伙伴系统的舒适化需要依赖memblock分配器释放到伙伴系统,因此需要先研究memblock。

2.伙伴系统初始化问题

        内核如何获取内存的地址、大小。整个内存已经被分为了相同大小的页帧,如何管理他们,如何将空闲页面放到伙伴系统呢?伙伴系统的初始化通常发生在内存管理初始化阶段,即mm_init函数执行期间。

(1)获取到内存区域的起始地址和大小(手册会规定dram区域的起始和结束)。

(2)伙伴系统的初始化(对物理内存管理)前:物理内存划分物理页帧后,需要填充到伙伴系统的链表上。系统启动初始化之后,有很多内存已经被占用了或者被保留起来了(例如dma,内核镜像等等)。因此,伙伴系统介入之前,整个内存是断断续续的。

(3)我们需要了解早期伙伴系统初始化之前的内存管理状态:此时需要先获取内存的管理信息(前面已经有memblock的管理了)。此时有一个全局变量struct memblock memblock保存了很多信息,记录了哪些被占用,占用多大等等。此时需要把空余的给伙伴系统进行管理。最终经过,memblock分配器的管理后,struct memblock memblock结构体的结构大概如下面所示,

(4)struct memblock memblock变量有两个信息:memory和reserved指针分别指向两个数组。数组里面是memblock_region类型的变量,记录了一段一段的空间。

 3. 全局变量:struct memblock memblock

如上图所示,很详细。

  • 可用物理内存:memblock.memory
  • reserve的物理内存:memblock.reserved
    • 内核镜像、dtb、uboot、页表
    • GPU

4.编程接口

        扫描物理内存上的块添加到memblock:memblock_add(phys_addr_t base, phys_addr_t size);删除使用memblock_remove(),什么情况下使用删除呢??

for_each_mem_range;遍历各个mem区域:

int memblock_reserve:主要是对memblock_type结构体reserve。该函数用于预留指定的物理内存区域,防止这部分内存被其他初始化过程使用。

int memblock_free: 主要是对memblock_type结构体free。该函数用于释放之前预留的物理内存区域,使其可用于其他用途。

memblock_add  该函数用于向memblock系统添加一个新的内存区域。

memblock_remove   该函数用于向memblock系统移除一个内存区域。

这些函数接口主要都是在memblock初始化过程中使用

通过调试接口查看信息:底下的reserved各个段就是memblock_type free指向的内容。

cat /sys/kernel/debug/memory

cat /sys/kernel/debug/reserved

5.memblock初始化

        Linux的memblock(内存块)系统是一种早期的内存管理机制,用于在内核完全初始化之前管理物理内存。它在内核启动早期使用,直到完整的内存管理系统(包括伙伴系统)初始化完成为止。

  1. 内核加载:当计算机启动时,BIOS/UEFI加载内核映像到内存,并跳转到内核的入口点开始执行。
  2. 基本硬件初始化:内核会进行一些基本的硬件初始化工作,比如设置CPU寄存器、中断控制器等。
  3. 内存检测:内核通过读取ACPI表或者通过内存检测来获取可用内存的信息。
    1. memblock模块加载:在内核加载早期,会加载memblock模块,用于管理内存。
    2. memblock初始化函数memblock_init函数被调用来初始化memblock系统。
    3. 初始化struct memblock结构体,这是memblock的核心数据结构,用于管理内存信息。设置全局变量memblock指向struct memblock实例。注册memblock_reserve和memblock_free等函数,用于在初始化过程中预留和释放内存。在内核初始化过程中,某些内存区域需要被预留,例如用于设备映射的内存。使用memblock_reserve函数来预留这些内存区域。
    4. struct memblock_region定义了内存区域的起始地址、结束地址以及是否可用等属性。使用memblock_add_*函数添加新的内存区域。所以终态就是把整个内存都处理好了,放到memory或者reserved

注意:early_init_dt_scan_memory函数主要用来初始化memory数组。early_init_fdt_scan_reserved_mem用来初始化reserved数组。最终状态就是将mem_block_memory_init_region和mem_block_reserved_init_region整个数组。 

总结下来主要有两个过程:

(1)获取物理内存的起始地址和大小:直接扫描设备树文件

(2)初始化全局变量memblock的两个数组

设备树中描述了memory和reserve的节点。所有的节点信息都是通过例如

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LuckyDog0623

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值