图片无法显示,请右键点击新窗口打开图片

BiscuitOS 内存管理之分页大专题订阅入口

构建一个用户空间分配器的目的是如何构建一个用户空间内存分配器,上图是分配器的最终效果,从代码上看是无法看出与 GLIBC 分配器的区别. 希望通过该文档的介绍让各位开发者学习到开发一个内存分配器所需的做的方面,另外分配器的构建是一个综合能力的考验,该分配器集成了分页大专题的多个知识点,也是对分页大专题的学习效果的考验。那么接下来全文将从零开始一步一步讲解构建逻辑, 尽可能让开发者可以边看边实践,看完就能构建一个可用的分配器.

用户空间内存分配器是用来为用户进程提供内存的,以满足用户进程存储数据的需求. 通过对分页大专题的学习,开发者可以围绕三个点进行展开: 虚拟内存物理内存页表,只要处理好三者的关系,那么一个分配器就可以构造出来. 在构造前需要思考三个问题:

  • 用户空间虚拟内存由谁负责分配?
  • 物理内存有谁提供?
  • 页表如何构建?

只要解决基础的三个问题,那么一个分配器就可以构建出来。接下来本文会边实践边讲解,涉及的技术细节在分页大专题里都有详细讲解,这里尽可能言简意赅的将重点放在如何构造出一个内存分配器出来。那么接下来通过部署一个实践案例在 BiscuitOS 上进行构建,实践案例在 BiscuitOS 上的部署逻辑如下:

cd BiscuitOS
make menuconfig

  [*] Package  --->
      [*] Paging Mechanism  --->
          [*] Paging Project: MM BASE --->

# 部署实践案例
make
# 源码目录
cd BiscuitOS/output/linux-6.0-x86_64/package/BiscuitOS-PAGING-EA-MM-default/
# 部署源码
make download
# 在 BiscuitOS 中实践
make build

BiscuitOS-PAGING-EA-MM-default Source Code on Gitee

部署完毕之后,开发者可以先在 BiscuitOS 上实践该案例,直接使用使用 ‘make build’ 命令即可,该实践案例是一个 MISC 驱动框架使用案例,可以直接在上面进行魔改,其中 app.c 是用户空间程序部分,main.c 则是内核模块部分。接下来的操作从这个实践案例上进行构建.

物理内存管理

在分页大专题里将物理内存划分成三类: OSMEM(系统管理的物理内存)RSVDMEM(系统预留的物理内存)以及 MMIO, 那么分配器要能分配内存,首先需要有自己可用的物理内存资源,这些物理内存资源可以来自这里介绍的三类. 对于给用户空间使用的内存,那么这里可以选择 OSMEM 或者 RSVDMEM, 本文为了尽可能简单讲述问题,这里选择 RSVDMEM 作为物理内存资源,开发者首先在内核的 CMDLINE 里添加 “memmap=256K$0x10000000” 字段,这样就可以获得 [0x10000000, 0x10040000) 区域就是一段预留物理内存,这段物理内存不会被内核管理, 添加过程是在 ‘BiscuitOS/output/linux-6.0-x86_64/RunBiscuitOS.sh’ 里添加如下:

RunBiscuitOS.sh 脚本里添加完毕之后,运行 BiscuitOS 系统之后,[0x10000000, 0x10040000) 区域就是一段预留物理内存。有了独立的物理内存资源之后,接下来是对物理内存进行管理,启动管理包括: 分配分配查找空闲区域 等. 管理物理内存的方法很多,这里采用最直观的方式: Bitmap, 也就是维护一个 Bitmap,每个 bit 代表一个长度为 PAGE_SIZE 的区域,如果这个 bit 置位那么表示物理页已经被分配,如果这个 bit 清零那么表示物理页空闲可分配,有了这个逻辑那么可以查询 Bitmap 获得指定长度的空闲物理内存, 具体代码实现如下:

图片无法显示,请右键点击新窗口打开图片

BiscuitOS 内存管理之分页大专题订阅入口

图片无法显示,请右键点击新窗口打开图片