1各个源文件具体位置
main.c : linux-4.5-rc1\init\main.c
setup.c :linux-4.5-rc1\arch\arm64\kernel\setup.c
init.c :linux-4.5-rc1\arch\arm64\mm\init.c
memblock.c :linux-4.5-rc1\mm\memblock.c
fdt.c :linux-4.5-rc1\drivers\of\fdt.c
of_reserved_mem.c :linux-4.5-rc1\drivers\of\of_reserved_mem.c
dma-contiguous.c :linux-4.5-rc1\drivers\base\dma-contiguous.c
dma-coherent.c :linux-4.5-rc1\drivers\base\dma-coherent.c
2.arm64_memblock_init
void __init arm64_memblock_init(void)
{
//找到最大的地址,然后把memblock.memory和memblock.reserved里面保存的地址信息大于最大地址的删除掉
memblock_enforce_memory_limit(memory_limit);
/*
* Register the kernel text, kernel data, initrd, and initial
* pagetables with memblock.
*/
//将kernel text, kernel data, initrd, and initial保存到保留内存
memblock_reserve(__pa(_text), _end - _text);
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start)
memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
#endif
//扫描所有配置为保留内存的节点
early_init_fdt_scan_reserved_mem();
/* 4GB maximum for 32-bit only capable devices */
if (IS_ENABLED(CONFIG_ZONE_DMA))
arm64_dma_phys_limit = max_zone_dma_phys();
else
arm64_dma_phys_limit = PHYS_MASK + 1;
//扫描所有dma节点
dma_contiguous_reserve(arm64_dma_phys_limit);
memblock_allow_resize();
memblock_dump_all();
}
这个函数主要作用如下:
1.memblock_enforce_memory_limit
找出memory最大的地址,然后对memblock.memory和memblock.reserved这两个内存保存的信息作调整,具体的过程如下:
1):这里面存储的地址信息都是从大到小保存的,如果某个地址大于最大地址而且长度又小于这个最大地址的长度,那么后面保存的信息全冲毁丢掉
2):如果某个地址小于最大地址,那么将这个地址赋值为最大地址,相应的size也要减小
3 ):如果以上条件不满足,那么其地址会被赋值为这个最大地址的结束位置
2.memblock_reserve(__pa(_text), _end - _text);保存kernel text, kernel data, initrd, and initial地址信息起始为_text,大小为_end-_text。然后调用memblock_reserve这个函数将这个信息添加到memblock.reserved这个数据里面,memblock.reserved这个函数的逻辑是:
1):如果memblock.reserved数据里面没有保存数据,那么将这个信息存放在第一个下标里面
2):如果里面有保存数据,那么就从里面找到地址大于等于需要插入信息的尾地址就行,也就是说保存的信息是按地址从大到小的方式保存的。而这种情况下,找到的下标位置可能已经保存了信息,所有后面还需要一个memorymover操作,将这个下标之后的数据统统后移一个结构体大小,免得信息被覆盖。
3.early_init_fdt_scan_reserved_mem
void __init early_init_fdt_scan_reserved_mem(void)
{
int n;
u64 base, size;