全部博文(71)
分类: LINUX
2008-04-22 11:08:55
根据上面的描述,需要有一个空闲块索引表作为某类大小空闲块队列的队头。从图2.2可知,该空闲块索引表项应该包含大小和一个用于连接的类型变量,下面的程序为ByCore实现的空闲块索引表项的类型:
struct free_struct{
list_t free_link;
uword_t size;
};
list_t类型变量free_link用于连接空闲块链表的第一个空闲块。对于一块物理内存,需要确定空闲索引表的两个参数,第一个是size域应该是多少?第二是空闲索引表到底应该有多少项?
这两个问题需要根据实际的大小空间来定。首先看看size域怎么确定,我的板子上一共有
现在看看个空闲块索引表到底应该有多少项?由于板子上需要管理的内存空间有6M空间,按照上面小节的描述,只需要建立一个size域为212 * MEM_PAGE_SIZE(但前为8M)的表项就可以了,该域后面连接大小大于4M,且小于等于8M的空闲块,而总共需要管理的内存空间才6M。如果仔细一点可以看出,2上面的指数就是索引表的表项序号,该序号从0开始编号。所以对于8M以下(包括8M),4M以上的物理内存,如果MEM_PAGE_SIZE等于2KB的话,只需建立13个表项就可以了。因此,ByCore使用了MEM_PAGE_LIST宏来定义表项的大小,针对我的板子是13。
到现在为止,根据上面小节的描述还有一个参数需要确定,那就是最小值阀值,这个阀值表示什么呢?它表示了系统运行过程中内存空闲块中出现的最小空闲块的大小。可能这样描述有点抽象,举个例子吧,假如当前内存中有一个大小为128Byte的空闲块,这时,有程序申请120Byte的内存空间,如果阀值定义为32Byte的话,内核应该将128Byte全部分配出去,而不会将128Byte大小的空闲块分割为两块。当然,如果申请的是96Byte,那么,大小为128Byte的内存块应被分成一个大小32Byte和一个大小为96Byte的块,前者插入到合适的空闲块链表中,后面的块分配给应用程序使用。OK,ByCore将该阀值也定义成了宏MEM_PAGE_LIMIT的形式,它的大小为32。
除了这些参数以外,还有两个参数是必须的,它们是:内存的大小,内存的起始地址。在ByCore中他们分别用宏MEM_SIZE和宏MEM_START_ADDR表示。最后还有两个标志需要说明一下就是MEM_FREE和MEM_ALLOC,它们分别表示内存块的状态,前者表示空闲,后者表示已分配。
综合一下,将这些宏一并列出如下:
#define MEM_FREE 0x0
#define MEM_ALLOC 0x1
#define MEM_SIZE (6*1024*1024)
#define MEM_PAGE_SIZE (2*1024)
#define MEM_START_ADDR 0x
#define MEM_PAGE_LIMIT 32
#define MEM_PAGE_LIST 13
下面该是一个重量级的任务登场了,什么任务呢?聪明的您应该想到了吧!上面到处都提到内存块,内存块的,这些内存块怎么表示啊!回想一下上面的分田的例子,想想村长手里的小本子上面记录的东西,下面就要构造一个结构来记录这些东西,这个东西就是所谓的重量级人物。该结构用来唯一的表示一个内存块(不管是空闲的,还是被占用的)。ByCore中定义的此结构如下:
typedef struct page_struct{
uword_t size;
uword_t status;
list_t free_link;
struct page_struct *mem_up;
struct page_struct *mem_down;
}page_t;
简单介绍一下里面的各个成员,其中:
·size,表示该内存块的大小,根据上面的描述,它的范围从32Byte到整个内存空间。
·status,存放了该内存块的状态,目前有空闲(MEM_FREE)和占用(MEM_ALLOC)两种状态。
·free_link,存放了下个空闲块的首地址,这些空闲块的大小都处于同一个级别。
·mem_up,该指针固定指向该内存块上面的内存块(空闲的或者非空闲的,上面的内存块是指它的最高内存地址比当前内存块的最低地址都低的内存块)。
·mem_down,该指针固定指向该内存块下面的内存块(空闲的或者非空闲的)。
OK!报告首长,到这里为止,ByCore用于管理内存方面的所有准备工作已经准备完毕,请首长指示!首长道:“继续”。
下面该干什么啊!不要着急,不要着急,休息休息!不过可以透露一下,下一节开始描述各个函数的实现了。这几天超级忙,先写到这里吧,下次把内存管理这章结束。