#include <stdlib.h>
int posix_memalign(void **memptr, size_t alignment, size_t size);
void *aligned_alloc(size_t alignment, size_t size);
void *valloc(size_t size);
#include <malloc.h>
void *memalign(size_t alignment, size_t size);
void *pvalloc(size_t size);
valloc 与 pvalloc(均为过时函数)
1.使用页的大小作为对齐长度
2.pvalloc:size预处理为 "向上取整 页的倍数"
aligned_alloc 与 memalign(后者过时函数)
1.使用alignment作为对齐长度(即:返回的地址为其倍数)
2.aligned_alloc要求:size should be a multiple of alignment.
思考1: aligned_alloc && memalign 与 valloc && pvalloc的联系?
官方说明: valloc() 等效于 memalign(sysconf(_SC_PAGESIZE),size).
思考2:malloc或realloc与上述函数的区别是什么?
malloc 或者realloc 返回的内存块地址都是8的倍数(如果是64位系统,则为16的倍数).
/***************** include/configs/platform-auto.h ***********/
/* Size of malloc() pool */
#define SIZE 0xC000000
#define CONFIG_SYS_MALLOC_LEN SIZE
/***************** include/common.h ***********************/
#define TOTAL_MALLOC_LEN (CONFIG_SYS_MALLOC_LEN + CONFIG_ENV_SIZE)
/***************** common/board_f.c **********************/
/* reserve memory for malloc() area */
static int reserve_malloc(void)
{
gd->start_addr_sp = gd->start_addr_sp - TOTAL_MALLOC_LEN;
debug("Reserving %dk for malloc() at: %08lx\n",
TOTAL_MALLOC_LEN >> 10, gd->start_addr_sp);
return 0;
}
static int initr_malloc(void)
{
ulong malloc_start;
#if CONFIG_VAL(SYS_MALLOC_F_LEN)
debug("Pre-reloc malloc() used %#lx bytes (%ld KB)\n", gd->malloc_ptr,
gd->malloc_ptr / 1024);
#endif
/* The malloc area is immediately below the monitor copy in DRAM */
malloc_start = gd->relocaddr - TOTAL_MALLOC_LEN;
mem_malloc_init((ulong)map_sysmem(malloc_start, TOTAL_MALLOC_LEN),
TOTAL_MALLOC_LEN);
return 0;
}
解释:
UBoot malloc可分配内存大小由宏TOTAL_MALLOC_LEN定义。
/******************common/dlmalloc.c******************/
void mem_malloc_init(ulong start, ulong size)
{
mem_malloc_start = start;
mem_malloc_end = start + size;
mem_malloc_brk = start;
debug("using memory %#lx-%#lx for malloc()\n", mem_malloc_start,
mem_malloc_end);
#ifdef CONFIG_SYS_MALLOC_CLEAR_ON_INIT
memset((void *)mem_malloc_start, 0x0, size);
#endif
malloc_bin_reloc();
}
void *sbrk(ptrdiff_t increment)
{
ulong old = mem_malloc_brk;
ulong new = old + increment;
/*
* if we are giving memory back make sure we clear it out since
* we set MORECORE_CLEARS to 1
*/
if (increment < 0)
memset((void *)new, 0, -increment);
if ((new < mem_malloc_start) || (new > mem_malloc_end))
return (void *)MORECORE_FAILURE;
mem_malloc_brk = new;
return (void *)old;
}
解释: 1. initr_malloc调用 mem_malloc_init()初始化了三个全局变量:
mem_malloc_start
mem_malloc_end
mem_malloc_brk。
2.分配内存时,sbrk()分配内存,并增加mem_malloc_brk的值;
3. 如果mem_malloc_brk超出范围,就报告错误。
注: malloc_simple.c里的alloc_simple是UBoot在没有搬运之前,简单的malloc的实现。
gd->malloc_base是可用内存的开始地址,
gd->malloc_ptr是当前可用的memory地址
gd->malloc_limit是可用内存的结束地址。