【微信群问题讨论】arm64_memory_present中的代码注释疑问
本文是原「蜗窝讨论区」的历史存档(2017-08-01),来自版块「Linux kernel技术问答」,共 1 帖。讨论区已停止服务,此处仅供查阅。
问题:请教一下, 为什么arm64_memory_present的注释要这么写"so must be done after the fixed reservations"
回答: fixed reservations是指在arm64_memblock_init中通过memblock_reserve保留地内存,包括 1、kernel text, kernel data, initrd, 以及起始阶段的页表。 2、通过dts,你也可以指定reserved的memory region,具体在early_init_fdt_scan_reserved_mem中处理 3、为DMA保留地连续内存,具体在dma_contiguous_reserve中处理。
arm64_memblock_init之后,memory block都已经初始化完毕,启动阶段的内存管理机制memblock已经OK,现在需要向真正的Linux内存管理机制(伙伴系统)转移。具体的转移过程中需要注意: 1、arm64_memblock_init之后,所有的memory type和reserved type的memory block都已经保存在相关的数据结构中。可以说memblock初始化完成 2、只有在memblock初始化完成,代码才可以调用memblock_alloc进行物理内存分配。但是不能访问其虚拟地址。为什么呢?因为没有建立页表。 3、在调用map_mem之前,只有很少一部分的物理内存建立了地址映射,包括kernel image,dtb等局部内存区域,初始阶段映射这些memory region就足够了 4、在调用map_mem之前,有两段内存已经是可见的(完成了地址映射),一个是kernel image段,另外一个是fdt段。,而广大的系统内存区域仍然在黑暗之中,等待我们去拯救(进行地址映射)。
经过上面的铺垫,我们再看看paging_init的代码: void __init paging_init(void) { void *zero_page;
map_mem(;
...... / allocate the zero page. / zero_page = early_alloc(PAGE_SIZE);
bootmem_init(;
......
void __init bootmem_init(void) { unsigned long min, max;
min = PFN_UP(memblock_start_of_DRAM();
max = PFN_DOWN(memblock_end_of_DRAM();
/*
- Sparsemem tries to allocate bootmem in memory_present(, so must be
- done after the fixed reservations.
*/
arm64_memory_present(;
在arm64_memory_present中,如果配置了CONFIG_SPARSEMEM,那么我们需要针对每一个memblock中的memory type的region,调用memory_present函数,声称该段memory当前状态是present的。 而在memory_present函数中会调用memblock_alloc分配物理内存,并通过虚拟地址访问分配的物理内存,正因为有这样的特点,因此arm64_memory_present必须: 1、在fixed reservation之后调用,否则有可能会命中kernel image或者dtb的物理内存区域。 2、必须在map_mem之后
