3) 条件
- 两个块具有相同的大小
- 它们的物理地址是连续的
- 页块大小相同
4、如何分配 4M 以上内存?
1) 为何限制大块内存分配
- 分配的内存越大, 失败的可能性越大
- 大块内存使用场景少
2) 内核中获取 4M 以上大内存的方法
- 修改 MAX_ORDER, 重新编译内核
- 内核启动选型传递"mem="参数, 如"mem=80M,预留部分内存;然后通过
- request_mem_region 和 ioremap_nocache 将预留的内存映射到模块中。需要修改内核启动参数, 无需重新编译内核. 但这种方法不支持 x86 架构, 只支持 ARM, PowerPC 等非 x86 架构
- 在 start_kernel 中 mem_init 函数之前调用 alloc_boot_mem 函数预分配大块内存, 需要重新编译内核
- vmalloc 函数,内核代码使用它来分配在虚拟内存中连续但在物理内存中不一定连续的内存
5、伙伴系统——反碎片机制
1) 不可移动页
- 这些页在内存中有固定的位置,不能够移动,也不可回收
- 内核代码段,数据段,内核 kmalloc() 出来的内存,内核线程占用的内存等
2) 可回收页
- 这些页不能移动,但可以删除。内核在回收页占据了太多的内存时或者内存短缺时进行页面回收3) 可移动页
- 这些页可以任意移动,用户空间应用程序使用的页都属于该类别。它们是通过页表映射的
- 当它们移动到新的位置,页表项也会相应的更新
6、slab 算法——基本原理
1) 基本概念
- Linux 所使用的 slab 分配器的基础是 Jeff Bonwick 为 SunOS 操作系统首次引入的一种算法
- 它的基本思想是将内核中经常使用的对象放到高速缓存中,并且由系统保持为初始的可利用状态。比如进程描述符,内核中会频繁对此数据进行申请和释放
2) 内部碎片
- 已经被分配出去的的内存空间大于请求所需的内存空间3) 基本目标
- 减少伙伴算法在分配小块连续内存时所产生的内部碎片
- 将频繁使用的对象缓存起来,减少分配、初始化和释放对象的时间开销
- 通过着色技术调整对象以更好的使用硬件高速缓存
7、slab 分配器的结构
- 由于对象是从 slab 中分配和释放的,因此单个 slab 可以在 slab 列表之间进行移动
- slabs_empty 列表中的 slab 是进行回收(reaping)的主要备选对象
- slab 还支持通用对象的初始化,从而避免了为同一目而对一个对象重复进行初始化
8、slab 高速缓存
1) 普通高速缓存
- slab 分配器所提供的小块连续内存的分配是通过通用高速缓存实现的
- 通用高速缓存所提供的对象具有几何分布的大小,范围为 32 到 131072 字节。
- 内核中提供了 kmalloc() 和 kfree() 两个接口分别进行内存的申请和释放
2) 专用高速缓存
- 内核为专用高速缓存的申请和释放提供了一套完整的接口,根据所传入的参数为具体的对象分配 slab 缓存
- kmem_cache_create() 用于对一个指定的对象创建高速缓存。它从 cache_cache 普通高速缓存中为新的专有缓存分配一个高速缓存描述符,并把这个描述符插入到高速缓存描述符形成的 cache_chain 链表中
- kmem_cache_alloc() 在其参数所指定的高速缓存中分配一个 slab。相反, kmem_cache_free() 在其参数所指定的高速缓存中释放一个 slab
9、内核态内存池
1) 基本原理
- 先申请分配一定数量的、大小相等(一般情况下) 的内存块留作备用
- 当有新的内存需求时,就从内存池中分出一部分内存块,若内存块不够再继续申请新的内存
- 这样做的一个显著优点是尽量避免了内存碎片,使得内存分配效率得到提升
2) 内核 API
- mempool_create 创建内存池对象
- mempool_alloc 分配函数获得该对象
- mempool_free 释放一个对象
- mempool_destroy 销毁内存池
10、用户态内存池
1) C 实例
11、dma 内存
1) 什么是 DMA
- 直接内存访问是一种硬件机制,它允许外围设备和主内存之间直接传输它们的 I/O 数据,而不需要系统处理器的参与2) DMA 控制器的功能
- 能向 CPU 发出系统保持(HOLD)信号,提出总线接管请求
- 当 CPU 发出允许接管信号后,负责对总线的控制,进入 DMA 方式
- 能对存储器寻址及能修改地址指针,实现对内存的读写操作
- 能决定本次 DMA 传送的字节数,判断 DMA 传送是否结束
- 发出 DMA 结束信号,使 CPU 恢复正常工作状态
2) DMA 信号
- DREQ:DMA 请求信号。是外设向 DMA 控制器提出要求,DMA 操作的申请信号
- DACK:DMA 响应信号。是 DMA 控制器向提出 DMA 请求的外设表示已收到请求和正进行处理的信号
- HRQ:DMA 控制器向 CPU 发出的信号,要求接管总线的请求信号。
- HLDA:CPU 向 DMA 控制器发出的信号,允许接管总线的应答信号: