块设备驱动1—用内存模拟磁盘

块设备驱动的引入

不能像字符设备那样直接进行读写操作,效率会很低。而是要
-
把读写放入队列

-         优化后再执行

 

块设备驱动的框架

app:        open    read    write  "test.text"
---------------------------------------------------------------- 
文件的读写
   
文件系统:        vfat, ext2, yaffs
---------------------------------------------------------------- 
扇区的读写
                         
块设备驱动程序
----------------------------------------------------------------  
     
硬件:             硬盘, flash

 

思路:
      -
(把文件的读写转化成扇区的读写)(电梯调度算法)
      -  
把读写放入队列

      -  调用队列的处理函数(优化/调顺序/合并/

 

块设备驱动程序编写:

1. 分配gendisk:alloc_disk
2.
设置
      2.1
分配/设置队列: blk_int_queue request_queuet         //提供读写能力

2.2 设置gendisk其它信息                                                    //提供属性
3.
注册:add_disk

 

举例:使用内存模拟硬盘块设备操作   (参考xd.c  z2ran.c)

1.  修改/drivers/block/Kconfig,增加以下内容

             config RAM_BLOCK_YE

                   tristate"YE Test Ram Block"


2.  修改/drivers/block/Makefile,增加以下内容 

    obj-$(CONFIG_RAM_BLOCK_YE)    += ramblock.o

 

3.  配置make menuconfig,选择为M

 

4.  生成驱动模块, makeM=drivers/block

 

注:以下是测试步骤,但目前驱动有问题,不能全部实现以下功能。

 

测试1

1. 安装驱动:   insmod ramblock.ko    

 

2. 格式化:    mk -> mkdosfs /dev/ramblock

 

3. 挂接:         cd/tmp -> mount/dev/ramblock /tmp/

 

4. 读写文件:   cd /tmp -> vi test.txt

 

5. 退出后,再挂接,查看是否有上次建立的文件:

                      umount /tmp/

                         mount /dev/ramblock /tmp/

 

6. 挂接到PC上:cat /dev/ramblock > /mnt/ramblock.bin

                    sudo mount -o loop ramblock.bin /mnt

 

7. 分区:    fd->  fdisk /dev/ramblock


附代码:

static struct gendisk *ramblock_disk;
static struct request_queue *ramblock_queue;
static int major;

static DEFINE_SPINLOCK(ramblock_lock);

#define RAMBLOCK_SIZE (1024*1024)
static unsigned char *ramblock_buf;

static int ramblock_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
     /* 容量=heads*cylinders*sectors*512 */
    geo->heads     = 2;
    geo->cylinders = 32;
    geo->sectors   = RAMBLOCK_SIZE/2/32/512;
    return 0;
}

static struct block_device_operations ramblock_fops = {
    .owner = THIS_MODULE,
    .getgeo = ramblock_getgeo,
};

static void do_ramblock_request(struct request_queue * q)
{
    struct request *req;

    req = blk_fetch_request(q);
    while (req) {
        unsigned long offset = blk_rq_pos(req) << 9;
        unsigned long len = blk_rq_cur_bytes(req);

        if (rq_data_dir(req) == READ)
        {
            memcpy(req->buffer, ramblock_buf+offset, len);
        }
        else
        {
            memcpy(ramblock_buf+offset, req->buffer, len);
        }

    __blk_end_request_cur(req, 1);
    }
}

static int ramblock_init(void)
{
    /* 1. 申请设备号 */
    major = register_blkdev(0, "ramblock");

   /* 2. 分配gendisk结构体 */
    ramblock_disk = alloc_disk(16);

    /* 3. 分配请求队列,绑定请求队列和请求函数 */
    ramblock_queue = blk_init_queue(do_ramblock_request, &ramblock_lock);

    /* 4. 给gendisk成员赋值 */
    ramblock_disk->major = major;
    ramblock_disk->first_minor = 0;
    ramblock_disk->fops = &ramblock_fops;
    sprintf(ramblock_disk->disk_name, "ramblock");
    ramblock_disk->queue = ramblock_queue;
    
    /* 5. 注册 */
    add_disk(ramblock_disk);
    //blk_register_region(MKDEV(major, 0), 8, THIS_MODULE,z2_find, NULL, NULL);

    return 0;
}

static void ramblock_exit(void)
{
    //blk_unregister_region(MKDEV(major, 0), 8);
    unregister_blkdev(major, "ramblock");
    del_gendisk(ramblock_disk);
    put_disk(ramblock_disk);
    blk_cleanup_queue(ramblock_queue);
    kfree(ramblock_buf);
}

module_init(ramblock_init);
module_exit(ramblock_exit);

MODULE_LICENSE("GPL");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值