当前位置:   article > 正文

__fdt_scan_reserved_mem_of: fdt: reserved memory: failed to reserve memory

of: fdt: reserved memory: failed to reserve memory for node

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  1. __reserved_mem_reserve_reg
    解析reserve memoy node的一个子节点,将其描述的物理地址范围添加到memblock.reserved中,由于每个子节点描述的物理地址范围可以是多个,因此会通过while循环遍历,此处会将第一个地址范围通过fdt_reserved_mem_save_node初始化reserved_mem。reserved_mem数组是通过静态分配的,主要用于存放struct reserved_mem结构体,用于描述reserved memory的每个子节点
/**
 * __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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  1. fdt_reserved_mem_save_node
    初始化reserved_mem为静态定义的数组
/**                                                                                                                                                                                                            
 * 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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/899341
推荐阅读
相关标签
  

闽ICP备14008679号