本文来分析setup_machine_fdt函数的代码
1.先讨论下dtb的物理地址变量__fdt_pointer
2.关于fixmap_remap_fdt已经在https://blog.csdn.net/snail_coder/article/details/94023887中谈论,这里不再提
3.谈论下early_init_dt_scan函数
关于__fdt_pointer
这个参数是由bootloader启动kernel时透过x0寄存器传递过来的,bootloader也就传递了这么一个参数过来,只是透过这个地址能获取到更多参数。
// kernel/msm-4.9/arch/arm64/kernel/head.S
preserve_boot_args:
mov x21, x0 // x21=FDT
__primary_switched:
str_l x21, __fdt_pointer, x5 // Save FDT pointer
顺便说下,这个保存的是物理地址,变量initial_boot_params保存的则是虚拟地址
fixmap_remap_fdt函数会返回dtb映射完成后的虚拟地址,这个虚拟地址之后会保存在initial_boot_params变量中:
setup_machine_fdt
early_init_dt_scan
early_init_dt_verify
bool __init early_init_dt_verify(void *params)
{
......
/* Setup flat device-tree pointer */
initial_boot_params = params;
......
}
最后看early_init_dt_scan函数
和内存初始化相关联的就是early_init_dt_scan_memory,其中会找到device_type = "memory"所在的node,获取到内存布局信息。
需要注意的是,dtb中这个内容不是静态的:在编译器件没有这个node,它是在bootloader中根据实际的内存状态添加进来的。
有个这个,memblock就知道内存的地址范围了。
early_init_dt_scan
early_init_dt_scan_nodes
early_init_dt_scan_memory
early_init_dt_add_memory_arch
memblock_add
// dts
memory {
device_type = "memory";
reg = <0x0 0x10000000 0x0 0x70000000 0x0 0x80000000 0x0 0x80000000>;
};