文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>vivi-stage2-step4

vivi-stage2-step4

时间:2010-06-07  来源:charming2440

经过了前面的步骤,此时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是配对出现的,申请的空间在使用完后应该及时的释放空间,否则会造成内存空间的不够。
相关阅读 更多 +
排行榜 更多 +
疯狂兔子人乐园

疯狂兔子人乐园

休闲益智 下载
空中飞机飞行

空中飞机飞行

休闲益智 下载
小姐姐历险记2

小姐姐历险记2

休闲益智 下载