Linux指定物理地址内存分配方法
Linux指定物理地址分配内存
在Linux内核中指定物理地址分配内存需要谨慎操作,通常涉及保留内存区域并将其映射到内核虚拟地址空间。以下是具体步骤和示例:
步骤说明
保留物理内存区域
在系统启动时,通过内核启动参数或设备树保留指定物理地址的内存,防止内核将其分配给其他用途。映射物理地址到内核虚拟地址
在内核模块中使用ioremap()
或memremap()
将保留的物理地址映射到内核的虚拟地址空间,以便访问。访问和释放内存
通过映射后的虚拟地址进行读写操作,使用完成后解除映射并释放资源。
具体实现
1. 保留物理内存
方法一:内核启动参数(x86/通用)
在GRUB等引导加载器中添加参数,保留指定区域:1
memmap=1M$0x10000000 # 保留从0x10000000开始的1MB内存
方法二:设备树(ARM/嵌入式)
在设备树中定义保留内存区域:1
2
3
4
5
6
7reserved-memory {
my_region: my_region@10000000 {
compatible = "my-reserved-memory";
reg = <0x10000000 0x00100000>; // 起始地址0x10000000,大小1MB
no-map; // 防止内核映射此区域
};
};
2. 内核模块映射物理地址
1 |
|
注意事项
物理地址合法性
确保指定的物理地址属于系统可用内存范围,且未被其他硬件(如DMA控制器)占用,否则可能导致系统崩溃。缓存一致性
使用ioremap()
默认映射为无缓存(Uncached),若需访问普通内存(如RAM),可改用memremap()
并指定MEMREMAP_WB
缓存模式:1
vaddr = memremap(PHYS_ADDR, MEM_SIZE, MEMREMAP_WB);
内存屏障
直接操作硬件寄存器或共享内存时,使用内存屏障(如mb()
)确保读写顺序。平台兼容性
x86架构可能启用物理地址扩展(PAE),需确认物理地址是否在32位可寻址范围内(或使用64位内核)。
用户空间访问物理内存
若需在用户空间访问指定物理地址,可通过 /dev/mem
设备结合 mmap
:
1 |
|
注意:需以root权限运行,且内核配置需启用 CONFIG_STRICT_DEVMEM
的宽松设置(不建议生产环境使用)。
通过上述方法,可以在Linux内核或用户空间中安全地分配并访问指定物理地址的内存。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Helloeuler!