/* * linux/kernel/blk_drv/ramdisk.c * * Written by Theodore Ts'o, 12/2/91 */
#include <string.h>
#include <linux/config.h> #include <linux/sched.h> #include <linux/fs.h> #include <linux/kernel.h> #include <asm/system.h> #include <asm/segment.h> #include <asm/memory.h>
#define MAJOR_NR 1//主设备号
#include "blk.h"
char *rd_start;//虚拟盘在内存中的开始位置
int rd_length = 0;//虚拟盘中的大小
void do_rd_request(void)//rd 当前请求项操作函数
{ int len; char *addr;
INIT_REQUEST; addr = rd_start + (CURRENT->sector << 9);//在物理内存对应的地址,起始位,sector*9 由扇区换成字节值
len = CURRENT->nr_sectors << 9;//长度
if ((MINOR(CURRENT->dev) != 1) || (addr+len > rd_start+rd_length)) {//对应的内存起始位置大于虚拟盘尾,所操作的内存地址一定要在虚拟盘的地址范围内的
end_request(0);//结束此请示项的请求处理
goto repeat; } if (CURRENT-> cmd == WRITE) {//写
(void ) memcpy(addr, CURRENT->buffer, len);//将当前请求项中的数据 缓冲区中的内容COPY到虚拟磁盘内存空间中来
} else if (CURRENT->cmd == READ) {//读
(void) memcpy(CURRENT->buffer, addr, len);//同前
} else panic("unknown ramdisk-command"); end_request(1);//结束此请示项的请求处理
goto repeat; }
/* * Returns amount of memory which needs to be reserved. */ long rd_init(long mem_start, int length)//main.c line 124 调用,
{ int i; char *cp;
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;//设置请求项处理函数指针
rd_start = (char *) mem_start;//虚拟盘在内存中的开始位置
rd_length = length;//虚拟盘中的大小
cp = rd_start; for (i=0; i < length; i++)//所需空间内存清0
*cp++ = '\0'; return(length);//返回虚拟盘所需内存的大小
}
/* * If the root device is the ram disk, try to load it. * In order to do this, the root device is originally set to the * floppy, and we later change it to be ram disk. */ void rd_load(void)//kernel/blk_drv/hd.c line 156 //尝试创建并加载虚拟盘,同是试着把根文件系统加载到虚拟盘中
{ struct buffer_head *bh;//高速缓冲块头指针
struct super_block s;//文件超级块结构
int block = 256; /* Start at block 256 *///开始于256块处,1块=1024字节,1扇区=512字节,1块=2扇区
int i = 1; int nblocks;//文件系统盘总块数
char *cp; /* Move pointer */ if (!rd_length)//检查长度
return; printk("Ram disk: %d bytes, starting at 0x%x\n", rd_length, (int) rd_start); if (MAJOR(ROOT_DEV) != 2)//根文件设备不是软盘设备
return; bh = breada(ROOT_DEV,block+1,block,block+2,-1);//读取指定的数据 块(软盘中的),返回含有数据块的缓冲区指针
if (!bh) { printk("Disk error while looking for ramdisk!\n"); return; } *((struct d_super_block *) &s) = *((struct d_super_block *) bh->b_data);//d_super_block 磁盘上超级块结构
brelse(bh);//释放缓冲区
if (s.s_magic != SUPER_MAGIC) /* No ram disk image present, assume normal floppy boot */ return; //以下把整个根文件系统读入到内存虚拟盘中
nblocks = s.s_nzones << s.s_log_zone_size; if (nblocks > (rd_length >> BLOCK_SIZE_BITS)) { printk("Ram disk image too big! (%d blocks, %d avail)\n", nblocks, rd_length >> BLOCK_SIZE_BITS); return; } printk("Loading %d bytes into ram disk... 0000k", nblocks << BLOCK_SIZE_BITS); cp = rd_start; while (nblocks) {//循环复制数据
if (nblocks > 2) bh = breada(ROOT_DEV, block, block+1, block+2, -1); else bh = bread(ROOT_DEV, block); if (!bh) { printk("I/O error on block %d, aborting load\n", block); return; } (void) memcpy(cp, bh->b_data, BLOCK_SIZE);//复制
brelse(bh); printk("\010\010\010\010\010%4dk",i); cp += BLOCK_SIZE; block++; nblocks--; i++; } printk("\010\010\010\010\010done \n"); ROOT_DEV=0x0101;//加载完后把根文件设备号修改为ROOT_DEV=0x0101
}
|