学写块设备驱动(一)----了解gendisk及request处理函数
来源:互联网 发布:软件项目成本多少钱 编辑:程序博客网 时间:2024/06/05 18:34
以下是一个最简单的块设备驱动,写完可以对编写块设备驱动的框架有初步了解。
环境:
Linux 2.6.29
源码:
simp_blkdev.c:
#include<linux/init.h>#include<linux/module.h>#include<linux/genhd.h>#include<linux/fs.h>#include<linux/blkdev.h>#define SIMP_BLKDEV_DISKNAME "simp_blkdev"#define SIMP_BLKDEV_DEVICEMAJOR COMPAQ_SMART2_MAJOR#define SIMP_BLKDEV_BYTES (8*1024*1024)static DEFINE_SPINLOCK(rq_lock);unsigned char simp_blkdev_data[SIMP_BLKDEV_BYTES];static struct gendisk *simp_blkdev_disk;static struct request_queue *simp_blkdev_queue;//device's request queuestruct block_device_operations simp_blkdev_fops = {.owner = THIS_MODULE,};//handle request that pass to this devicestatic void simp_blkdev_do_request(struct request_queue *q){struct request *req;while( (req = elv_next_request(q)) != NULL){if( ( (req->sector + req->current_nr_sectors)<<9) > SIMP_BLKDEV_BYTES ){printk(KERN_ERR SIMP_BLKDEV_DISKNAME ":bad request: block=%llu, count=%u\n",(unsigned long long )req->sector,req->current_nr_sectors);end_request(req,0);continue;}switch( rq_data_dir(req)){case READ:memcpy(req->buffer,(simp_blkdev_data + (req->sector<<9)),req->current_nr_sectors << 9);end_request(req,1);break;case WRITE:memcpy((simp_blkdev_data + (req->sector<<9)),req->buffer,req->current_nr_sectors << 9);end_request(req,1);break;}}}static int simp_blkdev_init(void){int ret;//init the request queue by the handler functionsimp_blkdev_queue = blk_init_queue(simp_blkdev_do_request,&rq_lock);if(!simp_blkdev_queue){ret = -ENOMEM;goto error_init_queue;}//alloc the resource of gendisksimp_blkdev_disk = alloc_disk(1);if(!simp_blkdev_disk){ret = -ENOMEM;goto error_alloc_disk;}//populate the gendisk structurestrcpy(simp_blkdev_disk->disk_name,SIMP_BLKDEV_DISKNAME);simp_blkdev_disk->major = SIMP_BLKDEV_DEVICEMAJOR;simp_blkdev_disk->first_minor = 0;simp_blkdev_disk->fops = &simp_blkdev_fops;simp_blkdev_disk->queue = simp_blkdev_queue;set_capacity(simp_blkdev_disk,SIMP_BLKDEV_BYTES>>9);add_disk(simp_blkdev_disk);printk("module simp_blkdev added.\n");return 0;error_init_queue:blk_cleanup_queue(simp_blkdev_queue);error_alloc_disk:return ret;}static void simp_blkdev_exit(void){del_gendisk(simp_blkdev_disk);put_disk(simp_blkdev_disk);blk_cleanup_queue(simp_blkdev_queue);printk("module simp_blkdev romoved.\n");}module_init(simp_blkdev_init);module_exit(simp_blkdev_exit);
Makefile:
obj-m := simp_blkdev.oKDIR = /lib/modules/$(shell uname -r)/buildall:$(MAKE) -C $(KDIR) M=$(PWD).PHONY:cleanclean:rm -f *.mod.c *.mod.o *.ko *.o *.tmp_versions *.markers *.symvers *.order
使用块设备:
insmod simp_blkdev.kolsmod | head
可以看到simp_blkdev模块,used by 列的值为0,说明未被使用
mkfs.ext3 /dev/simp_blkdevmount /dev/simp_blkdev /mnt/simp_blkdevlsmod | head
此时初始化文件系统并挂载,used by 列的值为1,说明被使用
cp /etc/init.d/* /mnt/simp_blkdevls /mnt/simp_blkdev
此时我们的块设备已经显得颇正常了,^ ^
rm -rf /mnt/simp_blkdevumount /mnt/simp_blkdevlsmod | head
simp_blkdev模块,used by 列的值重新为0
收获:
1. 要让一个最简单的块设备驱动可用,必须实现的关键结构为gendisk和request_queue。gendisk结构描述一个磁盘,包括主从设备号、设备操作函数、容量等信息,它通过gendisk->queue和request_queue联系起来,request_queue初始化时又向内核块设备层注册了处理request的函数(该例子中为simp_blkdev_do_request)。
2. 该版本适用于2.6.29内核,从2.6.31内核开始,一些api发生变化(见linux/include/blkdev.h)。在2.6.32内核中,
request -> sectors 变为 blk_rq_pos(request)
request -> nr_sectors 变为 blk_rq_nr_sectors(request)
elev_next_request(request) 变为 blk_fetch_request(request)
end_request(request, error) 变为 if (!__blk_end_request_cur(req, err)) {req = blk_fetch_request(q);}
参考:
http://bbs.chinaunix.net/thread-2017377-1-1.html
LDD3 chapter16
http://lwn.net/Articles/333620/
- 学写块设备驱动(一)----了解gendisk及request处理函数
- 学写块设备驱动(一)----了解gendisk及request处理函数
- gendisk,request与bio结构体;以及块设备驱动注册与注销,以及加载与卸载
- gendisk,request与bio结构体,以及块设备驱动注册与注销,以及加载与卸载
- gendisk,request与bio结构体,以及块设备驱动注册与注销,以及加载与卸载
- linux驱动学习--第二十五天:第十三章:Linux 块设备驱动(二):gendisk(通用磁盘) 结构体
- 字符设备驱动相关函数及数据结构简介 (ldd3)
- 字符设备驱动相关函数及数据结构简介 (ldd3)
- Linux设备驱动--字符设备(一)
- Linux设备驱动(一)
- 字符设备驱动(一)
- 块设备驱动(一)
- LINUX 设备驱动 (一)
- LCD设备驱动(一)
- 字符设备驱动(一)
- 字符设备驱动(一)
- 字符设备驱动(一)
- LINUX设备驱动之tty及console驱动(一)
- aix的smit快捷路径
- mac版本cornerstone的无限期破解方法
- R12 查询EBS用户相关SQL
- 网络连接类型判断
- 关掉机器上的firewall
- 学写块设备驱动(一)----了解gendisk及request处理函数
- "<>"、"!="、"not in"、"exsits"和"not exists"的使用规范
- ScannerTimeoutException 问题分析与解决方法
- 申请签证时工作单位证明英文摸版
- vi编辑器命令总结
- 一个能够递归执行的makefile小例子
- Indy IdTcpserver
- oracle插入日期时间
- 创业需要些什么