经过了前面的步骤,此时vivi是在ram中运行,内存管理系统(MMU)已经使能
接下来就是初始化堆
/*
* Now, vivi is running on the ram. MMU is enabled.
*/
/*
* Step 4:
* dynamic memory can be used in bootloader
*/
/* initialize the heap area*/
ret = heap_init();
if (ret) {
putstr("Failed initailizing heap region\r\n");
error();
}
|
来看看heap_init()函数
在堆初始化成功的情况下返回0
int heap_init(void)
{
return mmalloc_init((unsigned char *)(HEAP_BASE), HEAP_SIZE);
}
#define HEAP_BASE 0x33e00000
#define HEAP_SIZE SZ_1M
static blockhead *gHeapBase = NULL;
static inline int mmalloc_init(unsigned char *heap, unsigned long size)
{
if (gHeapBase != NULL)
return -1;
gHeapBase = (blockhead *)(heap);
gHeapBase->allocated = FALSE;
gHeapBase->signature = BLOCKHEAD_SIGNATURE;
gHeapBase->next = NULL;
gHeapBase->prev = NULL;
gHeapBase->size = size - sizeof(blockheap);
return 0;
}
typedef struct blockhead_t{
long signature; //标志,常置为BLOCKHEAD_SIGNATURE
char allocated; //占用标志,1为被占用,0为空
unsigned long size; //大小
struct blockhead_t *next; //指向后一个结构
struct blockhead_t *prev; //指向前一个结构
}blockhead;
|
这里需要注意的就是blockhead结构体,该结构体包含了5个成员,作用如上面解释的一样
到了这里我们再来看看在vivi中是如何申请内存空间的,申请内存调用mmalloc(unsigned long size);
void *mmalloc(unsigned long size)
{
blockhead *blockptr = gHeapBase;
blockhead *newblock;
char compacted = FALSE;
size = (size + 7) & ~7;
/*unsigned long align the size*/
DPRINTK("malloc(): size = 0x%08lx\n", size);
while(blockptr != NULL)
{
if (blockptr->allocted == FALSE)
{
if (blockptr->size >= size)
{
blockptr->allocated = TURE;
if ((blockptr->size - size) > sizeof(blockhead))
{
newblock = (blockhead *)((unsigned char *)(blockptr) +
sizeof(blockhead) + size);
newblock->signature = BLOCKHEAD_SIGNATURE;
newblock->prev = blockptr;
newblock->next = blockptr->next;
nweblock->size = blockptr->size - size - sizeof(blockhead);
newblock->allocated = FALSE;
blockptr->next = newblock;
blockptr->size = size;
}
else
{
}
break;
}
else
{
if ((blockptr->next == NULL) && (compacted == FALSE))
{
if (compact_head())
{
compacted = TURE;
blockptr = gHeapBase;
continue;
}
}
}
}
blockptr = blockptr->next;
}
PRTINTK("malloc(): returning blockptr = 0x%08lx\n", blockptr);
if (blockptr == NULL)
printk("Error: malloc(), out of storage. size = 0x%08lx\n", size);
return (blockptr != NULL) ? \
((unsigned char*)(blockptr)+sizeof(blockhead)) : NULL;
}
|
从上面这个函数我们就可以知道申请内存区域的方法:
首先是要找到一块没有使用的区域,并且这个区域要足够大
(最起码要大于等于所申请的空间大小+sizeof(blockhead))
然后是将该区域设置为已使用。然后赋值blockhead结构体内的变量
该函数返回所申请的地址的开始地址((unsigned char*)(blockptr)+sizeof(blockhead))
申请完了,现在来看看如何释放申请的空间,释放内存空间调用mfree()函数
void mfree(void *block)
{
blockhead *blockptr;
if (block == NULL)
return;
blockptr = (blockhead *)((unsigned char *)(block) - sizeof(blockhead));
if (blockptr->signature != BLOCKHEAD_SIGNATURE)
return;
blockptr->allocated = FALSE;
return;
}
|
看完了这对函数,我们知道mmalloc和mfree是配对出现的,申请的空间在使用完后应该及时的释放空间,否则会造成内存空间的不够。
阅读(1324) | 评论(0) | 转发(0) |