Linux reserved memory分析
来源:互联网 发布:污网络用语是啥意思 编辑:程序博客网 时间:2024/05/28 22:09
arch/arm/kernel/setup.c
void __init setup_arch(char **cmdline_p){arm_memblock_init(mdesc);paging_init(mdesc);}
void __init arm_memblock_init(const struct machine_desc *mdesc){early_init_fdt_reserve_self();early_init_fdt_scan_reserved_mem();}
/** * 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;/* Process header /memreserve/ fields */for (n = 0; ; n++) {fdt_get_mem_rsv(initial_boot_params, n, &base, &size);if (!size)break;early_init_dt_reserve_memory_arch(base, size, 0);}of_scan_flat_dt(__fdt_scan_reserved_mem, NULL);fdt_init_reserved_mem();}
of_scan_flat_dt是for循环遍历所有可能持有memory-region的节点,调用函数是__fdt_scan_reserved_mem
/** * 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;const char *status;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;//第一遍查找,找到"reserved-memory"并检查合法性/* scan next node */return 0;//完成第一遍查找任务} else if (!found) {/* scan next node */return 0;//现在是第二遍从查找,found=0表示第一遍没有找到"reserved-memory"所以宣布失败} else if (found && depth < 2) {/* scanning of /reserved-memory has been finished */return 1;}status = of_get_flat_dt_prop(node, "status", NULL);//如果有使用status,除了okay ok,其他字符串都表示disableif (status && strcmp(status, "okay") != 0 && strcmp(status, "ok") != 0)return 0;err = __reserved_mem_reserve_reg(node, uname);//核心reserve函数,需要有reg属性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;}
drivers/of/fdt.c
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);return memblock_reserve(base, size);}
到此,scan的工作完成了,下一个函数是init这些reserved memroy,重新回顾下
void __init early_init_fdt_scan_reserved_mem(void){of_scan_flat_dt(__fdt_scan_reserved_mem, NULL);fdt_init_reserved_mem();}
void __init fdt_init_reserved_mem(void){int i;/* check for overlapping reserved regions */__rmem_check_for_overlap();for (i = 0; i < reserved_mem_count; i++) {struct reserved_mem *rmem = &reserved_mem[i];unsigned long node = rmem->fdt_node;int len;const __be32 *prop;int err = 0;prop = of_get_flat_dt_prop(node, "phandle", &len);//memory region是通过phandle匹配,phandle就是设备持有的if (!prop)prop = of_get_flat_dt_prop(node, "linux,phandle", &len);if (prop)rmem->phandle = of_read_number(prop, len/4);if (rmem->size == 0)err = __reserved_mem_alloc_size(node, rmem->name, &rmem->base, &rmem->size);if (err == 0)__reserved_mem_init_node(rmem);}}
/** * res_mem_alloc_size() - allocate reserved memory described by 'size', 'align' * and 'alloc-ranges' properties */static int __init __reserved_mem_alloc_size(unsigned long node,const char *uname, phys_addr_t *res_base, phys_addr_t *res_size){ret = early_init_dt_alloc_reserved_memory_arch(size,align, start, end, nomap, &base);}
预留CMA的reserved memory
static int __init rmem_cma_setup(struct reserved_mem *rmem){phys_addr_t align = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order);phys_addr_t mask = align - 1;unsigned long node = rmem->fdt_node;struct cma *cma;int err;if (!of_get_flat_dt_prop(node, "reusable", NULL) || of_get_flat_dt_prop(node, "no-map", NULL))return -EINVAL;if ((rmem->base & mask) || (rmem->size & mask)) {pr_err("Reserved memory: incorrect alignment of CMA region\n");return -EINVAL;}err = cma_init_reserved_mem(rmem->base, rmem->size, 0, &cma);if (err) {pr_err("Reserved memory: unable to setup CMA region\n");return err;}/* Architecture specific contiguous memory fixup. */dma_contiguous_early_fixup(rmem->base, rmem->size);if (of_get_flat_dt_prop(node, "linux,cma-default", NULL))dma_contiguous_set_default(cma);rmem->ops = &rmem_cma_ops;rmem->priv = cma;pr_info("Reserved memory: created CMA memory pool at %pa, size %ld MiB\n",&rmem->base, (unsigned long)rmem->size / SZ_1M);return 0;}RESERVEDMEM_OF_DECLARE(cma, "shared-dma-pool", rmem_cma_setup);
节点要定义"shared-dma-pool",如
reserved-memory {#address-cells = <1>;#size-cells = <1>;ranges;cma_region: region@6a000000 {compatible = "shared-dma-pool";no-map;reg = <0x6a000000 0x1000000>;linux,cma-default;};
阅读全文
0 0
- Linux reserved memory分析
- linux memory 分析
- kdumpctl: No memory reserved for crash kernel.
- reserved
- Reserved
- linux out of memory分析
- linux out of memory分析
- Linux Out-of-Memory分析
- infotmic计算内存的方法 PMM Reserved Memory
- Troubleshooting Kdump error "Memory for crashkernel is not reserved"
- ERROR: insufficient memory reserved for statement tuplesort_mk.h:115
- failed to allocate XXXX bytes for committing reserved memory.
- dts中memreserve和reserved-memory的区别
- 64位ARMv8的芯片-reserved memory-mmu
- linux out of memory分析(OOM)
- Linux Out-Of-Memory(OOM) Killer分析
- Native memory allocation (mmap) failed to map 142606336 bytes for committing reserved memory.
- linux high memory/ low memory
- 欢迎使用CSDN-markdown编辑器
- 通过SSH录入数据库,出现乱码解决方案
- 富集分析一网打进
- Angular4 第四章 依赖注入基本概念
- leecode-easy-addbinary
- Linux reserved memory分析
- GIT 查看/修改用户名和邮箱地址 原创 2016年08月17日 13:36:39 标签:git 46999 用户名和邮箱地址的作用 用户名和邮箱地址是本地git客户端的一个变量,不随git库而改变
- cocos2d-x3.2 24种基本特效
- Retrofit 探索二:RxJava+Retrofit实现网络请求
- heartBleed漏洞检查python脚本
- sequelize格式化时间
- 第二部分Calendar原理和思想
- Vue学习日志:事件处理器(8)
- Ceres学习(四)