2.3 设置虚拟盘空间并初始化
接下来将对外设中的虚拟盘区进行设置。检查makefile文件中“虚拟盘使用标志”是否设置,以此确定本系统是否使用了虚拟盘。我们设定本书所用计算机有16 MB的内存,有虚拟盘,且将虚拟盘大小设置为2 MB。操作系统从缓冲区的末端起开辟2 MB内存空间设置为虚拟盘,主内存起始位置后移2 MB至虚拟盘的末端。图2-3展示了设置完成后的物理内存的规划格局。
调用rd_init()函数,开始对虚拟盘进行设置,具体执行代码如下:
//代码路径:init/main.c:
void main(void)
{
…
#ifdef RAMDISK
main_memory_start += rd_init(main_memory_start, RAMDISK*1024);
#endif
…
}
//代码路径:kernel/blk_drv/blk.h:
…
#define NR_BLK_DEV 7
…
struct blk_dev_struct {
void (*request_fn)(void);
struct request * current_request;
};
…
#if (MAJOR_NR== 1)
…
#define DEVICE_REQUEST do_rd_request
…
//代码路径:kernel/blk_drv/ll_rw_blk.c: //ll可以理解为low level
…
struct blk_dev_struct blk_dev[NR_BLK_DEV]= {
{ NULL, NULL }, /* no_dev */
{ NULL, NULL }, /* dev mem */
{ NULL, NULL }, /* dev fd */
{ NULL, NULL }, /* dev hd */
{ NULL, NULL }, /* dev ttyx */
{ NULL, NULL }, /* dev tty */
{ NULL, NULL } /* dev lp */
};
…
//代码路径:kernel/ramdisk.c:
…
#define MAJOR_NR 1
…
long rd_init(long mem_start, int length)//hd_init()、floppy_init()与此类似
{
int i;
char *cp;
blk_dev[MAJOR_NR].request_fn= DEVICE_REQUEST;//挂接do_rd_request()
rd_start= (char *) mem_start;
rd_length= length;
cp= rd_start;
for (i=0; i < length; i++)
*cp++= '\0'; //初始化为0
return(length);
}
在rd_init()函数中,先要将虚拟盘区的请求项处理函数do_rd_request()与图2-4中的请求项函数控制结构blk_dev[7]的第二项挂接。blk_dev[7]的主要功能是将某一类设备与它对应的请求项处理函数挂钩。可以看出我们讨论的操作系统最多可以管理6类设备。请求项将在2.6节中详细解释。这个挂接动作意味着以后内核能够通过调用do_rd_request函数处理与虚拟盘相关的请求项操作。挂接之后,将虚拟盘所在的内存区域全部初始化为0。图2-4表示了rd_init()函数的执行效果。
最后将虚拟盘区的长度值返回。这个返回值将用来重新设置主内存区的起始位置。