• 块设备驱动(使用内存模拟)


    驱动的完成步骤:

    1. 分配一个 gendisk 结构体
    2. 注册块设备
    3. 分配一个 request_queue 队列
    4. 配置 gendisk
    5. 完成上一篇框架中提到的 "处理函数"
    6. 添加磁盘 add_disk
    

    初始化程序如下

    static int ram_block_init(void)
    {
    	int major;
    	struct request_queue *queue;
    	struct gendisk *ramdisk;
    
        /* 分配 gendisk */
    	ramdisk = alloc_disk(1);
    
    	major = register_blkdev(0, DEVICE_NAME);
    
        /* 分配队列 */
    	queue = blk_init_queue(ram_block_request, &ramblock_lock);
    
        /* 配置 gendisk */
    	ramdisk->queue = queue;
    	ramdisk->major = major;
    	ramdisk->first_minor = 0;
    	ramdisk->fops = &ram_block_fops;
    
    	sprintf(ramdisk->disk_name, "RamBlock");
    	
    	/* 设置容量 */
    	set_capacity(ramdisk, RAMBLOCK_SIZE / 512);
    
        /* 分配一段空间供传输使用 */
    	ramblock_buf = kzalloc(RAMBLOCK_SIZE, GFP_KERNEL);
    
        /* 添加磁盘 */
    	add_disk(ramdisk);
    	
    	return 0;
    }
    
    module_init(ram_block_init);
    

    ram_block_fops 及 ramblock_getgeo 函数

    static struct block_device_operations ram_block_fops = {
    	.owner		= THIS_MODULE,
    	.getgeo		= ramblock_getgeo,
    };
    
    static int ramblock_getgeo(struct block_device *bdev, struct hd_geometry *geo)
    {
    	/* 配置磁盘的磁头、柱面和扇区数量 */
    	geo->heads     = 2;
    	geo->cylinders = 32;
    	geo->sectors   = RAMBLOCK_SIZE/2/32/512;
    	
    	return 0;
    }
    

    队列处理函数

    static void ram_block_request(struct request_queue *q)
    {
    	struct request *req;
    
        /* 获取到 request */
    	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);
    		
    		/* 如果队列没有结束,获取到下一个 request */
    		if (!__blk_end_request_cur(req, 0))
    			req = blk_fetch_request(q);
    	}
    }
    

    测试

    1. 编译并安装驱动
    2. 使用 mkdosfs 工具来格式化磁盘(mkdosfs /dev/RamBlock)
    3. mount 磁盘至一个文件夹,例如 /tmp
    4. 进入 /tmp 创建一个文件并写入内容
    5. umount 后再次 mount 查看文件内容
    

    参考:
    driverslockz2ram.c

  • 相关阅读:
    C#中子线程操作主线程中窗体上控件的方法
    关于VS2010在使用过程中的一些便捷之处
    WCF 开发日志 WCF契约设计
    OEA框架学习:运行时
    OEA框架学习:使用动软代码生成器
    OEA框架学习:多线程
    批处理定时自动更新SVN
    读书笔记:高效经理人的8个思维原则
    C# WinForm 技巧五:WinForm界面生成
    WCF开发日志 OEA里面的WCF设计
  • 原文地址:https://www.cnblogs.com/GyForever1004/p/8570110.html
Copyright © 2020-2023  润新知