ramdisk.c

680阅读 0评论2009-08-09 jhluroom
分类:LINUX

/*
 * 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

}

上一篇:ll_wr_blk.c
下一篇:floppy.c