Chinaunix首页 | 论坛 | 博客
  • 博客访问: 864490
  • 博文数量: 190
  • 博客积分: 7021
  • 博客等级: 少将
  • 技术积分: 1752
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-17 19:26
文章分类

全部博文(190)

文章存档

2014年(9)

2011年(32)

2010年(149)

我的朋友

分类: LINUX

2010-06-07 20:31:23

经过了前面的步骤,此时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是配对出现的,申请的空间在使用完后应该及时的释放空间,否则会造成内存空间的不够。
阅读(1319) | 评论(0) | 转发(0) |
0

上一篇:arm协处理器

下一篇:vivi-stage2-step5

给主人留下些什么吧!~~