1. anki
  2. SLUB
    1. 是什么
    2. 关键结构体
      1. struct slab(struct page )
      2. kmem_cache_cpu
        1. partial
      3. kmem_cache_node
      4. kmem_cache
    3. kfree
      1. Hardened Freelist
      2. Freelist randomization
    4. kmalloc
  3. 内核代码
  4. per-CPU
  5. cpio
    1. 解压
    2. 压缩
  6. kernel ROP

anki

SLUB

图解 SLUB 好直观的示例图

The SLUB allocator 清晰的笔记

是什么

slab 以字节为单位给结构体之类的东西分配空间。相对于 buddy 分配器分配大的空间,slab 分配器仍然从 Buddy 分配器中申请内存,之后自己对申请来的内存细分管理。

可以通过命令 sudo cat /proc/slabinfo 查看 slab 的使用情况。不过 wsl 没有 slab,不懂为啥wsl 内核不使用 slab。

关键结构体

SLUB schema

听说内核的内存比用户态更简单,因为matadata不是和data本身存在一起,而是保存在另外的结构体。真的假的。

metadata 大概指的是这个内存的信息

按照的顺序,如果直接从顶层结构体开始看会接触很多不了解的概念。

struct slab(struct page )

slab 结构体 用于记录一个或多个连续页面,被划分成的特定的结构体数组。关键的结构体成员有

有趣的是,为了节省空间(毕竟每一个被分配的页都需要有一个 slab 结构体,产生大量的开销),将 slab 结构体折叠到了原有的 page 结构体当中。这篇文章介绍了 page 结构体是怎么被塞入更多内容

这些 slab 可以分为 3 类:

kmem_cache_cpu

kmem_cache_cpu 是每个 cpu 用于管理正在使用中的 slab 以及可以供使用的 slab 的结构体。这是一个 per CPU 变量,因此每个 CPU 都是独有一份的。其中的关键结构体说明如下(结合上面的图看更直观一些)

partial

当图中右下角full slab释放obj的时候,首先就会将slab挂入per cpu partial链表管理。通过struct page中next成员形成单链表。per cpu partial链表指向的第一个page中会存放一些特殊的数据。例如:pobjects存储着per cpu partial链表中所有slab可供分配obj的总数,如图所示。当然还有一个图中没有体现的pages成员存储per cpu partial链表中所有slab缓存池的个数。pobjects到底有什么用呢?我们从full slab中释放一个obj就添加到per cpu partial链表,总不能无限制的添加吧!因此,每次添加的时候都会判断当前的pobjects是否大于kmem_cache的cpu_partial成员,如果大于,那么就会将此时per cpu partial链表中所有的slab移送到kmem_cache_node的partial链表,然后再将刚刚释放obj的slab插入到per cpu partial链表。如果不大于,则更新pobjects和pages成员,并将slab插入到per cpu partial链表

kmem_cache_node

per node partia链表类似per cpu partial,区别是node中的slab是所有cpu共享的,而per cpu是每个cpu独占的。假如现在的slab布局如上图所示。假如现在如红色箭头指向的obj将会释放,那么就是一个empty slab,此时判断kmem_cache_node的nr_partial是否大于kmem_cache的min_partial,如果大于则会释放该slab的内存。

kmem_cache

每一种大小或者类型的缓存都由 kmem_cahce 管理

重要字段比如

kfree

当一个对象被 free 时,它们将被添加到板 freelist 中。 kmem_cache_cpu.freelist指向了 freelist 中的第一个对象。freelist 中每个后续对象的地址都存储在前一个 free 对象内的偏移为 kmem_cache.offset 的位置。

关于 freelist 的保护有

Hardened Freelist

CONFIG_SLAB_FREELIST_HARDENED 安全加固宏是给freelist 链表指针进行混淆:

混淆后的指针=原指针 ^ 随机数random ^ 指针地址

Freelist randomization

CONFIG_SLAB_FREELIST_RANDOM 安全加固是将freelist 列表顺序随机化,正常freelist列表就是从开始往后按顺序排列,但如果开启了CONFIG_SLAB_FREELIST_RANDOM 则会打乱freelist 中object 的顺序,即便是刚申请好的新slab,其中的freelist 列表顺序也是随机的.

kmalloc

内核代码

内核代码一般在这个目录 /usr/src/linux。目录组成如下:

arch : 内核支持的硬件体系的代码

include: inlcude 文件

init: 启动代码

mm 内存管理

drivers 驱动

ipc进程通讯

fs 文件系统

kernel 主要核心代码

net 网络

lib 库代码

scripts 配置脚本

per-CPU

根据CPU的个数,在内存中生成多份拷贝,并且能够根据变量名和CPU编号,正确的对各个CPU的变量进行寻址。

同步与互斥_percpu变量

Reasons for Using Per-CPU Data

cpio

解压

cpio -idmv -D ./fs < rootfs.img

-i 解压

-d 按照压缩文件的目录解压

-m 按照原本的时间戳

-v 显示详细信息

-D 切换目录

压缩

kernel ROP