Linux 添加 memory block
需求
现在是这么一个情况,手头的一块开发板,在增加了内存后,需要在 Linux 系统里识别到、并能使用起来。
正常情况下,一般是重新配置 devicetree 即可。比如,按 内核文档 以及 devicetree 文档,可以这样配置若干片内存区域(当然这里的字段个数,取决于 #address-cells
和 #size-cells
):
memory@0 {
device_type = "memory";
reg = <0x000000000 0x00000000 0x00000000 0x80000000
0x000000001 0x00000000 0x00000001 0x00000000>;
};
这样在重新加载后即可生效,并可以通过查看 /proc/meminfo
、/proc/iomem
等方式来确认。
问题
现在碰到的问题是,在对 devicetree 进行修改并重新加载后,发现没有生效。
经过调试,目前猜测是 u-boot 里的一个开关 CONFIG_NR_DRAM_BANKS
限制了向 kernel 传递 devicetree 里对应 memory 字段的内容。但考虑到并没有提供 u-boot 源码,没办法重新编译,也就没办法确认问题原因,所以只能选择其他办法。
解决办法
对于 memory 字段,查找到 kernel 里的函数 early_init_dt_scan_memory()
是用来负责搜索和解析对应的内存区域:
/**
* early_init_dt_scan_memory - Look for and parse memory nodes
*/
int __init early_init_dt_scan_memory(unsigned long node, const char *uname,
int depth, void *data)
{
...
while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
u64 base, size;
base = dt_mem_next_cell(dt_root_addr_cells, ®);
size = dt_mem_next_cell(dt_root_size_cells, ®);
early_init_dt_add_memory_arch(base, size);
}
...
}
所以目前的解决办法是,在这个函数里,在某个时机主动调用一下 early_init_dt_add_memory_arch(base, size)
来添加内存,从而实现最开始的需求。