memblock工作原理

memblock是Linux启动阶段的一种内存管理方式,是对bootmem的补充,是为了应对bootmem易产生外部碎片而产生。他的初始化函数arm_memblock_init和bootmem初始化所在的函数paging_init紧挨着,都在setup_arch中。
struct memblock {
    phys_addr_t current_limit;
    phys_addr_t memory_size;    /* Updated by memblock_analyze() */
    struct memblock_type memory;
    struct memblock_type reserved;
};

current_limit:表示memblock可分配的内存地址的上限值,其初始化的过程为
               paging_init -> sanity_check_meminfo -> memblock_set current_limit(limit)
               其中limit = __pa(vmalloc_min-1) + 1 = VMALLOC_END - 128M = 4G - 128M(high mem)
memory_size:记录总的内存数量,在memory_analyze中更新
memory,reserved:是两张表格,前者是系统所拥有的物理内存块,后者可以理解为已分配的内存块

1. 初始化
     1)mdesc->reserve是在arch/arm/mach-omap2/board-d7800.c中分配给machine_desc变量。
     2)meminfo的初始化可以参考另外一篇笔记meminfo初始化

2.内存分配
     1)MEMBLOCK_ALLOC_ACCESSIBLE的值为0,则后面的max_addr也为0,但并不意味着搜索的上限也为0。在memblock_find_base中end,也就是搜索的上限(其实是搜索的起始值,因为我们的搜索时从内存的最高值开始的,这么做是有用意的,详见第2点)赋为memblock.current_limit,它的值可以参考本文前面的介绍。
     2)为什么是从内存的高地址开始搜索,mm/memblock.c中的有注释道
         /* We do a top-down search, this tends to limit memory
     * fragmentation by keeping early boot allocs near the
     * top of memory
     */
看起来是为了解决碎片的问题,但为什么能解决,不清楚。
     3)代码中的跟内存区的始末位置有关的值都进行了对齐,用到如下的语句
               size = memblock_align_up(size, align)
         base = memblock_align_down((end - size), align)
          这些也都是为了解决碎片问题,mm/memblock.c 中有注释,道
         /* We align the size to limit fragmentation. Without this, a lot of
     * small allocs quickly eat up the whole reserve array on sparc
     */
     4)memblock_addrs_overlap中判断交叠的方法很值得学习。