块设备驱动
来源:互联网 发布:windows 重叠io 编辑:程序博客网 时间:2024/05/16 13:46
http://bbs.chinaunix.net/thread-2017377-1-1.html
一下代码是<< 深入linux设备驱动程序内核机制>>中有关块设备的
http://blog.csdn.net/feixiaoxing/article/details/11701797
make_request
#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/types.h>#include <linux/fcntl.h>#include <linux/vmalloc.h>#include <linux/blkdev.h>#include <linux/hdreg.h>#define RAMHD_NAME "ramhd"#define RAMHD_MAX_DEVICE 2#define RAMHD_MAX_PARTITIONS 4#define RAMHD_SECTOR_SIZE 512#define RAMHD_SECTORS 16#define RAMHD_HEADS 4#define RAMHD_CYLINDERS 256#define RAMHD_SECTOR_TOTAL (RAMHD_SECTORS * RAMHD_HEADS *RAMHD_CYLINDERS)#define RAMHD_SIZE (RAMHD_SECTOR_SIZE * RAMHD_SECTOR_TOTAL) //8mbtypedef struct { unsigned char* data; struct request_queue* queue; struct gendisk* gd;}RAMHD_DEV;static char* sdisk[RAMHD_MAX_DEVICE] = {NULL};static RAMHD_DEV* rdev[RAMHD_MAX_DEVICE] = {NULL};static dev_t ramhd_major;static int ramhd_space_init(void){ int i; int err = 0; for(i = 0; i < RAMHD_MAX_DEVICE; i++){ sdisk[i] = vmalloc(RAMHD_SIZE); if(!sdisk[i]){ err = -ENOMEM; return err; } memset(sdisk[i], 0, RAMHD_SIZE); } return err;}static void ramhd_space_clean(void){ int i; for(i = 0; i < RAMHD_MAX_DEVICE; i++){ vfree(sdisk[i]); }}static int ramhd_open(struct block_device* bdev, fmode_t mode){ return 0;}static int ramhd_release(struct gendisk*gd, fmode_t mode){ return 0;}static int ramhd_ioctl(struct block_device* bdev, fmode_t mode, unsigned int cmd, unsigned long arg){ int err; struct hd_geometry geo; switch(cmd) { case HDIO_GETGEO: err = !access_ok(VERIFY_WRITE, arg, sizeof(geo)); if(err) return -EFAULT; geo.cylinders = RAMHD_CYLINDERS; geo.heads = RAMHD_HEADS; geo.sectors = RAMHD_SECTORS; geo.start = get_start_sect(bdev); if(copy_to_user((void*)arg, &geo, sizeof(geo))) return -EFAULT; return 0; } return -ENOTTY;}static struct block_device_operations ramhd_fops = { .owner = THIS_MODULE, .open = ramhd_open, .release = ramhd_release, .ioctl = ramhd_ioctl,};static int ramhd_make_request(struct request_queue* q, struct bio* bio){ char* pRHdata; char* pBuffer; struct bio_vec* bvec; int i; int err = 0; struct block_device* bdev = bio->bi_bdev; RAMHD_DEV* pdev = bdev->bd_disk->private_data; if(((bio->bi_sector * RAMHD_SECTOR_SIZE) + bio->bi_size) > RAMHD_SIZE){ err = -EIO; return err; } pRHdata = pdev->data + (bio->bi_sector * RAMHD_SECTOR_SIZE); bio_for_each_segment(bvec, bio, i){ pBuffer = kmap(bvec->bv_page) + bvec->bv_offset; switch(bio_data_dir(bio)){ case READ: memcpy(pBuffer, pRHdata, bvec->bv_len); flush_dcache_page(bvec->bv_page); break; case WRITE: flush_dcache_page(bvec->bv_page); memcpy(pRHdata, pBuffer, bvec->bv_len); break; default: kunmap(bvec->bv_page); goto out; } kunmap(bvec->bv_page); pRHdata += bvec->bv_len; } out: bio_endio(bio, err); return 0;}static int alloc_ramdev(void){ int i; for(i = 0; i < RAMHD_MAX_DEVICE; i++){ rdev[i] = kzalloc(sizeof(RAMHD_DEV), GFP_KERNEL); if(!rdev[i]){ return -ENOMEM; } } return 0;}static void clean_ramdev(void){ int i; for(i = 0; i < RAMHD_MAX_DEVICE; i++){ if(rdev[i]) kfree(rdev[i]); }}static int __init ramhd_init(void){ int i; ramhd_space_init(); alloc_ramdev(); ramhd_major = register_blkdev(0, RAMHD_NAME); for(i = 0; i < RAMHD_MAX_DEVICE; i++){ rdev[i]->data = sdisk[i]; rdev[i]->queue = blk_alloc_queue(GFP_KERNEL); blk_queue_make_request(rdev[i]->queue, ramhd_make_request); rdev[i]->gd = alloc_disk(RAMHD_MAX_PARTITIONS); rdev[i]->gd->major = ramhd_major; rdev[i]->gd->first_minor = i * RAMHD_MAX_PARTITIONS; rdev[i]->gd->fops = &ramhd_fops; rdev[i]->gd->queue = rdev[i]->queue; rdev[i]->gd->private_data = rdev[i]; sprintf(rdev[i]->gd->disk_name, "ramhd%c", 'a' +i); rdev[i]->gd->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO; set_capacity(rdev[i]->gd, RAMHD_SECTOR_TOTAL); add_disk(rdev[i]->gd); } return 0;}static void __exit ramhd_exit(void){ int i; for(i = 0; i < RAMHD_MAX_DEVICE; i++){ del_gendisk(rdev[i]->gd); put_disk(rdev[i]->gd); blk_cleanup_queue(rdev[i]->queue); } clean_ramdev(); ramhd_space_clean(); unregister_blkdev(ramhd_major, RAMHD_NAME);}module_init(ramhd_init);module_exit(ramhd_exit);MODULE_AUTHOR("dennis__chen@ AMDLinuxFGL");MODULE_DESCRIPTION("The ramdisk implementation with request function");MODULE_LICENSE("GPL");
http://blog.csdn.net/qingtian2006/article/details/8825880
0 0
- Linux块设备驱动
- Linux块设备驱动
- 块设备驱动分析
- 块设备驱动编写
- 块设备驱动
- 块设备驱动层
- Linux块设备驱动
- 块设备驱动分析
- linux块设备驱动
- 块设备驱动设计
- 块设备驱动---RAMDISK
- Linux块设备驱动
- linux 块设备驱动
- Linux块设备驱动
- linux块设备驱动
- linux块设备驱动
- Linux 块设备驱动
- 块设备驱动总结
- 白话压缩感知(含Matlab代码)
- 数据库执行过程下篇
- 我的故事,我的家
- 手机照片误删后怎么才能恢复
- <a href="javascript:void(0)" onclick="ff()" ></a> 用法解析
- 块设备驱动
- OpenCV基础篇之绘图及RNG随机数对象
- javascript模拟实现java重载
- 统计信息及DBMS_STATS.GATHER_TABLE_STATS学习
- 创建oracle用户并赋予dba角色的权限
- sql之left join、right join、inner join的区别
- Libpng的编译和安装
- JQuery插件实现网页首次登录提示/页面功能介绍引导/教程式引导/下一步介绍功能
- 页游中资源版本更新问题之解决方案