1. 内存管理与DMA:那些年踩过的坑
刚接触嵌入式开发那会儿,总觉得内存管理和DMA是黑盒子——数据往里一扔,能跑就行。直到某次项目因为内存对齐问题导致DMA传输随机失败,设备在客户现场频繁崩溃,我才真正意识到这潭水有多深。今天就把这些年调试内存和DMA时踩过的坑、总结的经验一次性讲透,从kmalloc到dma_alloc_coherent的底层差异,再到实战中的避坑指南,全是血泪换来的干货。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 内存分配机制深度解析
2.1 kmalloc:通用内存分配的陷阱
kmalloc是内核最常用的内存分配器,但用它处理DMA时处处是坑。我曾在STM32F407上用kmalloc分配DMA缓冲区,结果发现传输到第17次必然丢数据。后来用cat /proc/vmallocinfo查看,才发现kmalloc在内存压力大时会返回非物理连续的内存。
关键特性:
- 默认返回虚拟地址连续的内存
- 物理连续性仅在小尺寸(通常≤4KB)时保证
- 对齐方式受SLAB分配器影响
c复制// 典型错误用法:
char *buf = kmalloc(2048, GFP_KERNEL);
dma_addr_t dma_handle = dma_map_single(dev, buf, 2048, DMA_TO_DEVICE);
警告:超过PAGE_SIZE的kmalloc分配绝不能直接用于DMA!
2.2 vmalloc:大内存分配的代价
当需要分配大于4KB的非连续内存时,很多开发者会转向vmalloc。我在视频处理项目中就犯过这个错误——用vmalloc分配了8MB的帧缓冲区,结果DMA性能暴跌90%。
根本原因:
- vmalloc通过MMU映射非连续物理页
- 每次DMA传输需要TLB刷新和页表遍历
- 对Cache一致性不友好
实测数据对比(RK3399平台):
| 分配方式 | 传输1MB耗时(ms) | CPU占用率 |
|---|---|---|
| kmalloc(4KBx256) | 2.1 | 15% |
| vmalloc(1MB) | 18.7 | 83 |
