本文共 1932 字,大约阅读时间需要 6 分钟。
第二阶段建立的是 memblock
ATAG_MEM 或ATAG_CMDLINE mem=size@startmemblock 的管理范围 是 u-boot 决定的u-boot 可以在这个过程中 预留内存
从 start_kernel->setup_arch->paging_init->bootmem_init->memblock_allow_resize 返回到 kernel_init(进程1) -> free_initmem 其实从 mem_init返回 -> free_initmem ,memblock 其实只是能用而已在这个阶段,已经存在一个buddy了, memblock 如果也使用的话,就会造成内存管理的混乱(两个内存管理器管理了大约相同的内存)memblock 相关的函数 都是 用 __init 修饰的,在 free_initmem 的时候会被释放掉所以就再也不能用 memblock_alloc 来申请内存了.实际上 mm_init 函数执行之前 , 就没有使用过 memblock_alloc 了
alloc方法 是 memblock_allocmemblock_alloc memblock_alloc_try_nid memblock_alloc_internal phys_addr_t alloc = memblock_alloc_range_nid // 1. 找到起始物理地址 phys_addr_t found = memblock_find_in_range_node __memblock_find_range_bottom_up for_each_free_mem_range round_up // 2. reserve 这段地址 memblock_reserve(found, size); return found; return phys_to_virt(alloc);
free方法 是 memblock_freememblock_free memblock_remove_range(&memblock.reserved, base, size); // 如果该内存块在 memblock.reserved 成员 范围内,则需要先将其摘出来成为一个 memblock.reserved 成员(即 memblock.reserved) // 例如 memblock.reserved 一个成员A 为 0x0000 0000 - 0x2000 0000 // 而你要free 的 内存区域 为 0x1000 0000 - 0x2000 0000 // 就需要将 A 删掉 // 新增 B : 0x0000 0000 - 0x1000 0000 // 新增 C : 0x1000 0000 - 0x2000 0000 memblock_isolate_range(type, base, size, &start_rgn, &end_rgn); // 隔离 // 将 B 移除 memblock_remove_region(type, i);
memblock_reserve memblock_add_range(&memblock.reserved, base, size, MAX_NUMNODES, 0); // 第一次 // memblock.reserved 的第一个成员 type->regions[0].base = base; type->regions[0].size = size; type->regions[0].flags = flags; // 第(N>=2)次 // memblock.reserved 的 第二个成员 第一次循环 : // memblock.reserved 增加数组大小 memblock_double_array insert = true; 第二次循环 : // 先 插入 if (base < end) if (insert) memblock_insert_region(type, idx, base, end - base, nid, flags) // 再 merge memblock_merge_regions(type);
转载地址:http://ujigi.baihongyu.com/