找回密码
立即注册
搜索
发回帖 发新帖

5239

积分

0

好友

665

主题
发表于 2 小时前 | 查看: 12| 回复: 0

前言

在 Linux 驱动开发里,不管是创建设备私有数据结构、接收用户空间数据,还是构造 DMA Buffer,几乎每一步都绕不开内存分配。很多驱动的 probe() 函数一上来就要申请一块内存保存设备状态。正因如此,掌握内核内存分配 API 是驱动开发非常基础的一环。内核中有多个内存分配函数,它们之间到底有什么区别?下面逐一拆解。

常用内存分配函数

kmalloc / kzalloc

void *kmalloc(size_t size, gfp_t flags)
void *kzalloc(size_t size, gfp_t flags)

这是内核中最常用的通用分配接口。分配出来的内存不仅在虚拟地址上连续,在物理地址上也是连续的。

  • 分配机制:建立在 Slab / Slub 内存池 之上,可以避免小块内存分配造成的碎片。
  • GFP 标志:
    • GFP_KERNEL:最常用的标志,可能会挂起或睡眠以等待空闲页,不可在中断上下文使用。
    • GFP_ATOMIC:原子分配,绝不睡眠,适合在中断处理程序或持有自旋锁时使用。
  • kzalloc 的区别:相比 kmalloc,它会自动调用 memset(ptr, 0, size),常用于避免信息泄露或未初始化指针问题。

示例:

struct my_data *data;

data = kmalloc(sizeof(*data), GFP_KERNEL);
if (!data)
    return -ENOMEM;

vmalloc / vzalloc

void *vmalloc(unsigned long size)
void *vzalloc(unsigned long size)

分配在虚拟地址上连续、但物理地址不一定连续的大块内存。

  • 分配机制:通过从 Buddy System 多次申请单个独立物理页,再在内核页表中构建连续映射。
  • 优点:能够分配极大的连续虚拟空间,不容易因物理内存碎片而失败。

示例:

void *buf;
buf = vzalloc(16 * 1024 * 1024);

alloc_pages

struct page *alloc_pages(gfp_t gfp_mask, unsigned int order)

这是基于 Buddy System 的底层页分配接口。

  • 分配机制:以阶(Order)为单位分配 2^order 个物理页,例如 order=0 表示 1 页,order=3 表示 8 页。

示例:

struct page *page;
void *addr;
// order = 2 分配页数 = 2^2 = 4 pages
page = alloc_pages(GFP_KERNEL, 2);
// 虚拟地址
addr = page_address(page);

dma_alloc_coherent()

void *dma_alloc_coherent(struct device *dev, size_t size,
                         dma_addr_t *dma_handle, gfp_t gfp)

设备驱动中与硬件进行 DMA 交互时专用的内存分配接口。

  • 特点:保证物理地址连续,同时自动建立 CPU 与 DMA 外设之间的 Cache 一致性映射。

示例:

void *cpu_addr;       // CPU使用的地址
dma_addr_t dma_addr;  // DMA使用的地址

cpu_addr = dma_alloc_coherent(dev, size, &dma_addr, GFP_KERNEL);

总结

函数 物理地址 常用分配大小 中断上下文安全 特点
kmalloc 连续 小内存(一般小于128KB) 是(取决于 GFP 标志) 基于 Slab/Slub 分配器;速度最快,含物理连续开销
kzalloc 连续 小内存(一般小于128KB) 是(取决于 GFP 标志) 同 kmalloc,但分配后自动清零内存内容
vmalloc 不连续 大内存 否 通过修改页表映射离散页;有页表重映射开销
alloc_pages 连续 按页分配 是(取决于 GFP 标志) 内核最基础的页级分配器
dma_alloc_coherent 连续 根据设备 DMA 需求而定 否 硬件 DMA 专用;提供一致性映射

更多 Linux 内核与驱动开发话题,欢迎到 云栈社区 一起交流。




上一篇:Linux内核DMA-BUF跨设备共享内存与fd传递机制详解
下一篇:KV Cache 凭什么吃掉2GB显存?从Attention到GQA/MLA完整拆解
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-10-25 08:28 , Processed in 0.071668 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表