赞
踩
kenrel: 5.10
arch: arm64
如果节点名字为reserved-memory,则意味着找到了这个节点,则下一次遍历时会遍历reserved-memory的子节点,每个子节点描述了具体的预留地址范围,这个地址范围可能包含多组address,size 对,对于每个子节点查看nomap属性如果有定义,则需要从memblock.memory中移除对应的物理地址范围所涵盖的memblock_region,并添加到memblock.reserved中,如果没有定义,则只会添加到memblock.reserved中
/** * fdt_scan_reserved_mem() - scan a single FDT node for reserved memory */ static int __init __fdt_scan_reserved_mem(unsigned long node, const char *uname, int depth, void *data) { static int found; int err; if (!found && depth == 1 && strcmp(uname, "reserved-memory") == 0) { if (__reserved_mem_check_root(node) != 0) { pr_err("Reserved memory: unsupported node format, ignoring\n"); /* break scan */ return 1; } found = 1; /* scan next node */ return 0; } else if (!found) { /* scan next node */ return 0; } else if (found && depth < 2) { /* scanning of /reserved-memory has been finished */ return 1; } if (!of_fdt_device_is_available(initial_boot_params, node)) return 0; err = __reserved_mem_reserve_reg(node, uname); if (err == -ENOENT && of_get_flat_dt_prop(node, "size", NULL)) fdt_reserved_mem_save_node(node, uname, 0, 0); /* scan next node */ return 0; }
/** * __reserved_mem_reserve_reg() - reserve all memory described in 'reg' property */ static int __init __reserved_mem_reserve_reg(unsigned long node, const char *uname) { int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32); phys_addr_t base, size; int len; const __be32 *prop; int first = 1; bool nomap; prop = of_get_flat_dt_prop(node, "reg", &len); if (!prop) return -ENOENT; if (len && len % t_len != 0) { pr_err("Reserved memory: invalid reg property in '%s', skipping node.\n", uname); return -EINVAL; } nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL; while (len >= t_len) { base = dt_mem_next_cell(dt_root_addr_cells, &prop); size = dt_mem_next_cell(dt_root_size_cells, &prop); if (size && early_init_dt_reserve_memory_arch(base, size, nomap) == 0) pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n", uname, &base, (unsigned long)size / SZ_1M); else pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %ld MiB\n", uname, &base, (unsigned long)size / SZ_1M); len -= t_len; if (first) { fdt_reserved_mem_save_node(node, uname, base, size); first = 0; } } return 0; }
/** * fdt_reserved_mem_save_node() - save fdt node for second pass initialization */ void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname, phys_addr_t base, phys_addr_t size) { struct reserved_mem *rmem = &reserved_mem[reserved_mem_count]; if (reserved_mem_count == ARRAY_SIZE(reserved_mem)) { pr_err("not enough space for all defined regions.\n"); return; } rmem->fdt_node = node; rmem->name = uname; rmem->base = base; rmem->size = size; reserved_mem_count++; return; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。