博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux块设备驱动之内存模拟块设备
阅读量:7195 次
发布时间:2019-06-29

本文共 2650 字,大约阅读时间需要 8 分钟。

用内存代替块设备的总结,相对来简单得多,对内存操作想必大家都很熟悉,直接分配一块内存就可以直接读写操作了
/* 参考:
 * drivers\block\xd.c
 * drivers\block\z2ram.c
 */
#define RAMBLOCK_SIZE (1024*1024)//一个扇区是512字节
 
static struct gendisk *ramblock_disk;
static struct request_queue *ramblock_queue;
static DEFINE_SPINLOCK(ramblock_lock);//定义一个自旋锁
static unsigned char *ramblock_buf;
static struct block_device_operations ramblock_fops = {//fops结构体,必须要。
.owner = THIS_MODULE,
.getgeo = ramblock_getgeo,//设置heads /cylinders/sectors
};
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 int ramblock_init(void)
{
/* 1. 分配一个gendisk结构体 */
ramblock_disk = alloc_disk(16); /* 次设备号个数: 分区个数+1 */
/* 2. 设置 */
/* 2.1 分配/设置队列: 提供读写能力 */
ramblock_queue = blk_init_queue(do_ramblock_request, &ramblock_lock);//do_ramblock_request请求队列函数
ramblock_disk->queue = ramblock_queue;
/* 2.2 设置其他属性: 比如容量 */
major = register_blkdev(0, "ramblock");  /* cat /proc/devices */
ramblock_disk->major       = major;
ramblock_disk->first_minor = 0;
sprintf(ramblock_disk->disk_name, "ramblock");//把ramblock打印到ramblock_disk->disk_name
ramblock_disk->fops        = &ramblock_fops;
set_capacity(ramblock_disk, RAMBLOCK_SIZE / 512);//设置容量
. 硬件相关操作 */
ramblock_buf = kzalloc(RAMBLOCK_SIZE, GFP_KERNEL);//分配一个读写缓冲区
/* 4. 注册 */
add_disk(ramblock_disk);
}
static void do_ramblock_request(struct request_queue * q)//当读写的时候调用这个函数
{
static int r_cnt = 0;
static int w_cnt = 0;
struct request *req;
//printk("do_ramblock_request %d\n", ++cnt);
while ((req = elv_next_request(q)) != NULL) {
/* 数据传输三要素: 源,目的,长度 */
/* 源/目的: */
unsigned long offset = req->sector * 512;//偏移值为
/* 目的/源: */
// req->buffer
/* 长度: */
unsigned long len = req->current_nr_sectors * 512;
if (rq_data_dir(req) == READ)
{
//printk("do_ramblock_request read %d\n", ++r_cnt);
memcpy(req->buffer, ramblock_buf+offset, len);
}
else
{
//printk("do_ramblock_request write %d\n", ++w_cnt);
memcpy(ramblock_buf+offset, req->buffer, len);
}
end_request(req, 1);//表示读写完成,必须写,不然会卡在那里,只有重新开关机
}
}
}
static void ramblock_exit(void)
{
unregister_blkdev(major, "ramblock");
del_gendisk(ramblock_disk);
put_disk(ramblock_disk);
blk_cleanup_queue(ramblock_queue);
kfree(ramblock_buf);
}
测试如下:
在开发板上:
1. insmod ramblock.ko
2. 格式化: mkdosfs /dev/ramblock
3. 挂接: mount /dev/ramblock /tmp/
4. 读写文件: cd /tmp, 在里面vi文件
5. cd /; umount /tmp/
6. cat /dev/ramblock > /mnt/ramblock.bin
7. 在PC上查看ramblock.bin
   sudo mount -o loop ramblock.bin /mnt
测试5th:
1. insmod ramblock.ko
2. ls /dev/ramblock*
3. fdisk /dev/ramblock
块设备常用的几个命令:
m:寻求帮助  n:增加一个新的分区  w:保存分区

转载地址:http://mgxkm.baihongyu.com/

你可能感兴趣的文章
ngResource提交json数据如何带参数
查看>>
五步学习法 - 俗却有道理
查看>>
xmind8
查看>>
Filter 配置多个URL-PATTERN
查看>>
使用渐进式JPEG来提升用户体验
查看>>
2 笔经小结
查看>>
C# 操作摄像头
查看>>
maven的几个重要配置文件pom.xml、settings.xml;Maven打包生成包含所有依赖的jar包...
查看>>
ReLU为什么比Sigmoid效果好
查看>>
优秀的博客链接地址
查看>>
CentOS 配置防火墙操作实例(启、停、开、闭port)
查看>>
深入浅出 spring-data-elasticsearch - 基本案例详解(三
查看>>
Android 6.0 最简单的权限获取方法 RxPermition EasyPermition
查看>>
Linux多线程实践(四 )线程的特定数据
查看>>
openssl ca(签署和自建CA)
查看>>
在ceph中:pool、PG、OSD的关系
查看>>
Hash分析
查看>>
[精]Odoo 8.0深入浅出开发教程-模块开发基础
查看>>
在linux下的使用复制命令cp,不让出现“overwrite”(文件覆盖)提示的方法。(转)...
查看>>
推荐几篇网狐好文
查看>>