本文来分析arm64_memblock_init函数的代码
这个函数的主要作用是初始化memblock。关于memory的区间范围,已经在setup_machine_fdt函数中添加进来。这里主要是remove掉no-map的区域,并reserve一些关键区域:如kernel镜像、dtb块、ramdisk镜像和device tree中的一些需要reserve的节点。
查看代码发现,有对ramdisk和kernel进行reserve,没有dtb,因为在setup_machine_fdt中已经完成了。
除此之外,就是要从dts中解析memreserve and reserved-memory,进行memblock reserve和memblock remove(no-map的不归kernel管)
还申请了一个公共的CMA区域:16MB
之后memblock就算初始化完成,可以进行resize了
void __init arm64_memblock_init(void)
{
// RAM的起始物理地址,1GB对齐
// For [0x10000000, 0xffffffff], memstart_addr = 0x0
// For [0x40000000, 0xffffffff], memstart_addr = 0x40000000
// For [0x80000000, 0xffffffff], memstart_addr = 0x80000000
memstart_addr = round_down(memblock_start_of_DRAM(),
ARM64_MEMSTART_ALIGN);
// reserve [initrd_start, initrd_end)
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && initrd_start) {
u64 base = initrd_start & PAGE_MASK;
u64 size = PAGE_ALIGN(initrd_end) - base;
memblock_remove(base, size); /* clear MEMBLOCK_ flags */
memblock_add(base, size);
memblock_reserve(base, size);
}
}
// reserve [_text, _end)
memblock_reserve(__pa_symbol(_text), _end - _text);
// handle memreserve and reserved-memory in dts
early_init_fdt_scan_reserved_mem();
// for current project, it is 4GB
arm64_dma_phys_limit = max_zone_dma_phys();
high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
// Default contiguous memory area size:
// CONFIG_CMA_SIZE_MBYTES=16
// CONFIG_CMA_SIZE_SEL_MBYTES=y
// [ 0.000000] cma: Reserved 16 MiB at 0x00000000f2400000
// It is stored at struct cma *dma_contiguous_default_area
dma_contiguous_reserve(arm64_dma_phys_limit);
memblock_allow_resize();
}