memblock初始化过程中fdt mem处理
导读
本部分将memblock 初始化时FDT中reserved memory的扫描处理细化整理,调用情况如下:
code目录:
涉及到的目录 | 简单描述 |
---|---|
./kernel-4.9/include/linux/of_reserved_mem.h | reserved_mem 结构相关定义位置 |
./kernel-4.9/include/linux/of.h | _OF_DECLARE宏定义位置 |
./kernel-4.9/drivers/of/fdt.c | fdt 接口实现位置 |
./kernel-4.9/scripts/dtc/libfdt/fdt_ro.c | fdt_get_mem_rsv实现位置 |
./kernel-4.9/drivers/of/of_reserved_mem.c | fdt和reserved mem相关函数实现位置 |
1. 调用入口
这个函数是扫描reserve节点,添加到memblock管理中
/**
* early_init_fdt_scan_reserved_mem() - create reserved memory regions
*
* This function grabs memory from early allocator for device exclusive use
* defined in device tree structures. It should be called by arch specific code
* once the early allocator (i.e. memblock) has been fully activated.
*/
void __init early_init_fdt_scan_reserved_mem(void)
{
int n;
u64 base, size;
if (!initial_boot_params) return;//是否已经可以访问到FDT
/* Process header /memreserve/ fields */
for (n = 0; ; n++) {
//在dts中有些vendor会定义memreserve,地址和size,会在这里读取并配置为reserved,当前平台没有配置这个
//像这样:/memreserve/ 0x80000000 0x00010000;
fdt_get_mem_rsv(initial_boot_params, n, &base, &size);//读取地址
if (!size) break;
early_init_dt_reserve_memory_arch(base, size, 0);//针对这些地址,如果是nomap则从memblock中删除,否则标记为memblock reserve
}
of_scan_flat_dt(__fdt_scan_reserved_mem, NULL);//主要找到的是这个:扫描所有节点,并对每个节点调用__fdt_scan_reserved_mem
fdt_init_reserved_mem();
}
处理的入口函数,做三件事:
- 对memreserve fields的地址添加处理:标记nomap的从memblock中删除,其他的添加到memblock.reserve中;
- 扫描设备树中的所有节点,找到reserved-memory节点及其子节点,解析其地址范围;
- 对于找到的需要reserved的地址空间,添加处理
这个函数是在扫描所有FDT的设备节点,并针对于每一个节点调用回调;
1.1 memreserve部分处理
从FDT中获取到base和size:fdt_get_mem_rsv(initial_boot_params, n, &base, &size)
int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
{
FDT_CHECK_HEADER(fdt);
*address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);//将address写入到传入的地址中
*size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);//将size写入到传入的地址中
return 0;
}
int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base, phys_addr_t size, bool nomap)
{
if (nomap) return memblock_remove(base, size);//标记有nomap则将其从memblock管理中删除;
return memblock_reserve(base, size);//没有标记nomap,则添加到reserve region中
}
这里处理很简单,不做过多分析;
1.2 FDT扫描
本部分来看具体扫描FDT节点过程;
核心函数是:of_scan_flat_dt(__fdt_scan_reserved_mem, NULL),先上code:
/**
* of_scan_flat_dt - scan flattened tree blob and call callback on each.
* @it: callback function
* @data: context data pointer
*
* This function is used to scan the flattened device-tree, it is used to extract the memory information at boot before we can unflatten the tree
*/
int __init of_scan_flat_dt(int (*it)(unsigned long node, const char *uname, int depth, void *data), void *data)
{
const