块设备驱动程序3
来源:互联网 发布:基金怎么玩 知乎 编辑:程序博客网 时间:2024/05/18 00:40
Virtual_blkdev.c
//============================================================================ // Name : Virtual_blkdev // Author : Haier // Version : 0.3 // Copyright : Your copyright notice // Description : blkdev driver in c, Ansi-style , compile by GCC, Linux 2.6.32 //============================================================================ #include <linux/module.h>#include <linux/moduleparam.h>#include <linux/init.h>#include <linux/version.h>#include <linux/sched.h>#include <linux/kernel.h>#include <linux/slab.h>#include <linux/fs.h>#include <linux/errno.h>#include <linux/timer.h>#include <linux/types.h>#include <linux/fcntl.h>#include <linux/hdreg.h>#include <linux/kdev_t.h>#include <linux/vmalloc.h>#include <linux/genhd.h>#include <linux/blkdev.h>#include <linux/buffer_head.h>#include <linux/bio.h>#define VIRTUAL_BLKDEV_DEVICEMAJOR COMPAQ_SMART2_MAJOR#define VIRTUAL_BLKDEV_DISKNAME "Virtual_blkdev"#define VIRTUAL_BLKDEV_BYTES (8*1024*1024)#define VIRTUAL_BLKDEV_MAXPARTITIONS (5)static struct request_queue *Virtual_blkdev_queue;static struct gendisk *Virtual_blkdev_disk;unsigned char Virtual_blkdev_data[VIRTUAL_BLKDEV_BYTES];static int Virtual_blkdev_getgeo(struct block_device *bdev, struct hd_geometry *geo){if(VIRTUAL_BLKDEV_BYTES < 16 * 1024 * 1024){geo->heads = 1;geo->sectors = 1;}else if(VIRTUAL_BLKDEV_BYTES < 512 * 1024 * 1024){geo->heads = 1;geo->sectors = 32;}else if(VIRTUAL_BLKDEV_BYTES < 16ULL * 1024 * 1024 * 1024){geo->heads = 32;geo->sectors = 32;}else {geo->heads = 255;geo->sectors = 63;}geo->cylinders = (VIRTUAL_BLKDEV_BYTES >> 9) / (geo->heads/geo->sectors);return 0;}static int Virtual_blkdev_make_request(struct request_queue *q, struct bio *bio){struct bio_vec *bvec;int i;void *dsk_mem;if((bio->bi_sector << 9) + bio->bi_size > VIRTUAL_BLKDEV_BYTES){printk(KERN_ERR VIRTUAL_BLKDEV_DISKNAME": bad request: block=%llu, count=%u\n",(unsigned long long)bio->bi_sector, bio->bi_size);#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)bio_endio(bio, 0, -FIO);#elsebio_endio(bio, -EIO);#endifreturn 0;}dsk_mem = Virtual_blkdev_data + (bio->bi_sector << 9);bio_for_each_segment(bvec, bio, i){void *iovec_mem;switch(bio_rw(bio)){case READ:case READA:{iovec_mem = kmap(bvec->bv_page) + bvec->bv_offset;memcpy(iovec_mem, dsk_mem, bvec->bv_len);kunmap(bvec->bv_page);break;}case WRITE:{iovec_mem = kmap(bvec->bv_page) + bvec->bv_offset;memcpy(dsk_mem, iovec_mem, bvec->bv_len);kunmap(bvec->bv_page);break;}default:{printk(KERN_ERR VIRTUAL_BLKDEV_DISKNAME": unknown value of bio_rw: %lu\n",bio_rw(bio));#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)bio_endio(bio, 0, -EIO);#elsebio_endio(bio, -EIO);#endifreturn 0;}}dsk_mem += bvec->bv_len;}#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)bio_endio(bio, bio->bi_size, 0);#else bio_endio(bio, 0);#endifreturn 0;}struct block_device_operations Virtual_blkdev_fops ={.owner = THIS_MODULE,.getgeo = Virtual_blkdev_getgeo,};static int __init Virtual_blkdev_init(void){int ret;Virtual_blkdev_disk = alloc_disk(VIRTUAL_BLKDEV_MAXPARTITIONS);if(!Virtual_blkdev_disk){ret = -ENOMEM;goto err_alloc_disk;}Virtual_blkdev_queue = blk_alloc_queue(GFP_KERNEL);if(!Virtual_blkdev_queue){ret = -ENOMEM;goto err_init_queue;}blk_queue_make_request(Virtual_blkdev_queue, Virtual_blkdev_make_request);strcpy(Virtual_blkdev_disk->disk_name, VIRTUAL_BLKDEV_DISKNAME);Virtual_blkdev_disk->major = VIRTUAL_BLKDEV_DEVICEMAJOR;Virtual_blkdev_disk->first_minor = 0;Virtual_blkdev_disk->fops = &Virtual_blkdev_fops;Virtual_blkdev_disk->queue = Virtual_blkdev_queue;set_capacity(Virtual_blkdev_disk, VIRTUAL_BLKDEV_BYTES>>9);add_disk(Virtual_blkdev_disk);return 0;err_init_queue:put_disk(Virtual_blkdev_disk);err_alloc_disk:return ret;}static void __exit Virtual_blkdev_exit(void){del_gendisk(Virtual_blkdev_disk);put_disk(Virtual_blkdev_disk);blk_cleanup_queue(Virtual_blkdev_queue);}module_init(Virtual_blkdev_init);module_exit(Virtual_blkdev_exit);
Makefile
target = Virtual_blkdevifeq ($(KERNELRELEASE),)KERNELDIR ?= /lib/modules/`uname -r`/buildmodules:$(MAKE) -C $(KERNELDIR) M=`pwd` modulesmodules_install:insmod $(target).kouninstall:rmmod $(target).koclean:rm -rf *.o *.mod.c *.ko *.symvers *.order *.unsignedelseobj-m := $(target).oendif
0 0
- 块设备驱动程序3
- 块设备驱动程序实现
- 13. 块设备驱动程序
- 块设备驱动程序
- 装载块设备驱动程序
- 块设备驱动程序框架
- 块设备驱动程序
- 块设备驱动程序
- .块设备驱动程序框架
- 块设备驱动程序
- 块设备驱动程序
- 块设备驱动程序之一
- 块设备驱动程序设计
- 块设备驱动程序<一>
- 块设备驱动程序<二>
- 块设备驱动程序
- 块设备驱动程序1
- 块设备驱动程序2
- printf记录程序日志
- 程序设计基石与实践之应用多态性的工资发放系统
- java中Comparator的用法
- 鸭子-策略模式(Strategy)
- redhat7 禁用ip6
- 块设备驱动程序3
- T4模板基础
- 为什么做竞品分析,竞品分析怎么做?
- 1004. Counting Leaves (30)
- LEETCODE: Balanced Binary Tree
- Add Two Numbers leetcode
- 一些快捷常用命令included in the safari,mac, terminal
- iOS开发的一些技巧
- sql统计占比和统计数量