bootmem API总结

bootmem_init()函数执行完成后,linux启动初期的bootmem分配器就初始化完成了,可以调用bootmem提供的API分配内存。

这些API在include/linux/bootmem.h中定义

1.alloc_bootmem与alloc_bootmem_pages的不同之处在于分配内存时的对齐方式不同,

alloc_bootmem以cache_line大小对齐,

alloc_bootmem_pages以页大小对齐。

#define alloc_bootmem(x) \
    __alloc_bootmem(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))

#define alloc_bootmem_pages(x) \
    __alloc_bootmem(x, PAGE_SIZE, __pa(MAX_DMA_ADDRESS))

2.alloc_bootmem在分配失败时会panic,而alloc_bootmem_nopanic分配失败时返回NULL。

#define alloc_bootmem(x) \
    __alloc_bootmem(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
#define alloc_bootmem_nopanic(x) \
    __alloc_bootmem_nopanic(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))

3.alloc_bootmem预留出DMA分配区;alloc_bootmem_low从0开始分配。

#define alloc_bootmem(x) \
    __alloc_bootmem(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))

#define alloc_bootmem_low(x) \
    __alloc_bootmem_low(x, SMP_CACHE_BYTES, 0)

4.在多节点的系统中,有多个bootmem分配器构成的链表。

alloc_bootmem没有指定节点信息,分配时遍历bootmem分配器链表,遇到第一个分配成功的就返回。

alloc_bootmem_node则在指定的节点的bootmem分配器上分配内存。

#define alloc_bootmem(x) \
    __alloc_bootmem(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))

#define alloc_bootmem_node(pgdat, x) \
    __alloc_bootmem_node(pgdat, x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))

5.释放内存

/**
 * free_bootmem_node - mark a page range as usable
 * @pgdat: node the range resides on
 * @physaddr: starting address of the range
 * @size: size of the range in bytes
 *
 * Partial pages will be considered reserved and left as they are.
 *
 * The range must reside completely on the specified node.
 */
void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
                  unsigned long size)
{
    unsigned long start, end;

    start = PFN_UP(physaddr);
    end = PFN_DOWN(physaddr + size);

    mark_bootmem_node(pgdat->bdata, start, end, 0, 0);
}

/**
 * free_bootmem - mark a page range as usable
 * @addr: starting address of the range
 * @size: size of the range in bytes
 *
 * Partial pages will be considered reserved and left as they are.
 *
 * The range must be contiguous but may span node boundaries.
 */
void __init free_bootmem(unsigned long addr, unsigned long size)
{
    unsigned long start, end;

    start = PFN_UP(addr);
    end = PFN_DOWN(addr + size);

    mark_bootmem(start, end, 0, 0);
}

 

posted @ 2018-08-14 20:47  bluebluebluesky  阅读(139)  评论(0编辑  收藏  举报