Peng Fan +

Linux reserved memory part 1

在kernel启动时,early_init_fdt_Scan_reserved_mem负责构建rmem数组。

 682 /**
 683  * early_init_fdt_scan_reserved_mem() - create reserved memory regions
 684  *
 685  * This function grabs memory from early allocator for device exclusive use
 686  * defined in device tree structures. It should be called by arch specific code
 687  * once the early allocator (i.e. memblock) has been fully activated.
 688  */
 689 void __init early_init_fdt_scan_reserved_mem(void)
 690 {
 691         int n;
 692         u64 base, size;
 693
 694         if (!initial_boot_params)
 695                 return;
 696
 697         /* Process header /memreserve/ fields */
 698         for (n = 0; ; n++) {
 699                 fdt_get_mem_rsv(initial_boot_params, n, &base, &size);
 700                 if (!size)
 701                         break;
 702                 early_init_dt_reserve_memory_arch(base, size, 0);
 703         }
 704
 705         of_scan_flat_dt(__fdt_scan_reserved_mem, NULL);
 706         fdt_init_reserved_mem();
 707 }

此处initial_boot_params其实是device tree所在的虚拟地址。

699行,查询memreserve结点,然后702行会把相应的address space写入一个memblock结构体, memblock结构主要是在用在kernel boot阶段,我们知道kernel使用的是buddy page系统, 在kernel启动过程中,会有一个从memblock到buddy page的切换过程,所有没有被标记为reserve的 memblock会被释放然后迁移到buddy page系统,这也就意味着,所以被reserve的memblock,不会 进入buddy page系统,也就不会被kernel的mm子系统所管理。

705行,遍历所有的dts节点,执行__fdt_scan_reserved_mem函数,这里面核心的代码主要是:

 674         err = __reserved_mem_reserve_reg(node, uname);
 675         if (err == -ENOENT && of_get_flat_dt_prop(node, "size", NULL))
 676                 fdt_reserved_mem_save_node(node, uname, 0, 0);

__reserved_mem_reserve_reg,获取reg里面的address和size,以及no-map属性。然后在 memblock系统里面reserve这部分memory,同时fdt_reserved_mem_save_node把相关的信息 存入reserved_mem数组,方便后面使用。如果没有提供reg属性,那么就只在reserved_mem中 创建一个entry存储相关信息,但这里的base和size给的值都为0,和dts里面我们一般给一个size不一致。 这里的主要目的是为了和reg区分。如果这里的size被赋值,那么后面就没法区分是否有提供reg属性了。 在fdt_init_reserved_mem中会检测size,如果size为0,那么表示这个rmem不是基于reg的,就会 重新从dts里面获取size值。

fdt_init_reserved_mem 分配和初始化所有的reserved memory regions.

所有__reservedmem_of_table中的项都是通过ESERVEDMEM_OF_DECLARE来注册的。

Blog

Opinion

Project