实验七补充sbull虚拟的磁盘驱动的编写.docx

上传人:b****5 文档编号:8045563 上传时间:2023-01-28 格式:DOCX 页数:19 大小:22.89KB
下载 相关 举报
实验七补充sbull虚拟的磁盘驱动的编写.docx_第1页
第1页 / 共19页
实验七补充sbull虚拟的磁盘驱动的编写.docx_第2页
第2页 / 共19页
实验七补充sbull虚拟的磁盘驱动的编写.docx_第3页
第3页 / 共19页
实验七补充sbull虚拟的磁盘驱动的编写.docx_第4页
第4页 / 共19页
实验七补充sbull虚拟的磁盘驱动的编写.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

实验七补充sbull虚拟的磁盘驱动的编写.docx

《实验七补充sbull虚拟的磁盘驱动的编写.docx》由会员分享,可在线阅读,更多相关《实验七补充sbull虚拟的磁盘驱动的编写.docx(19页珍藏版)》请在冰豆网上搜索。

实验七补充sbull虚拟的磁盘驱动的编写.docx

实验七补充sbull虚拟的磁盘驱动的编写

sbull虚拟的磁盘驱动的编写

分类:

Embedded[ARM/DSP...]驱动2011-11-2817:

24191人阅读评论(0)收藏举报

原理指导:

我们通过vmalloc在内存中开辟一部分空间,作为一个虚拟的磁盘,然后我们以块设备的方式来访问这片内存,例如这个sbull模型。

sbull(Simple Block Utility for Loading Localities),该驱动程序实现了一个使用系统内存的块设备,从本质上讲,属于一种 RAM 磁盘驱动程序。

字符设备的IO操作则是直接不绕弯的,块设备的IO操作会配对和整合。

驱动的任务是处理请求,对于这些请求的排队和整合的工作有IO调度算法处理。

所以块设备的核心工作就是:

请求处理函数或者是制造请求。

Block_devices_operations结构体中没有读写一类的成员函数,而只是包含打开、释放和IO控制等函数。

块设备的流程:

(1)先把模块模型搭建好

MODULE_LICENSE("Dual BSD/GPL");

static struct block_device_operations sbull_ops = {

.owner           = THIS_MODULE,

.open          = sbull_open,

.release  = sbull_release,

.media_changed   = sbull_media_changed,

.revalidate_disk = sbull_revalidate,

.ioctl         = sbull_ioctl,

.getgeo= sbull_getgeo,

};

module_init(sbull_init);

module_exit(sbull_exit);

(2)定义一个我们用内存虚拟出来的块设备sbull_dev

struct sbull_dev {

        int size;                       /* Device size in sectors */

        u8 *data;                       /* The data array */

        short users;                    /* How many users */

        short media_change;             /* Flag a media change?

 */

        spinlock_t lock;                /* For mutual exclusion */

        struct request_queue *queue;    /* The device request queue */

        struct gendisk *gd;             /* The gendisk structure */

        struct timer_list timer;        /* For simulated media changes */

};

这个设备结构体是我们工作的核心,也许你不知道需要哪些成员,不要紧,还是那句话,编写驱动的时候,需要设备表现出那些性质和功能,相应的添加上就OK了。

(3)设备的初始化 

sbull_init(  ){

一、sbull_major = register_blkdev(sbull_major, "sbull");

二、Static struct sbull_dev *Devices = kmalloc(ndevices*sizeof (struct sbull_dev), GFP_KERNEL);//在这里可以对Kmalloc的结果判断下,然后进一步处理...

三、setup_device()跳到我们设备注册函数中去

}//初始化函数结束

(4)开始注册我们的这个设备

 setup_device(  ){  //安装(注册)一个设备前,一定要保证它被初始化了

这些成员都得出初始化好:

    一、    int size;                       /* Device size in sectors */

        u8 *data;                       /* The data array */

        short users;                    /* How many users */

        spinlock_t lock;                /* For mutual exclusion */

        struct request_queue *queue;    /* The device request queue */

        struct gendisk *gd;             /* The gendisk structure */

    二、add_disk(dev->gd);//这个重要的注册函数}//函数结束

(5)扇区大小、data数组、user、锁lock的初始化:

一、dev->size = nsectors*hardsect_size;

dev->data = vmalloc(dev->size);

spin_lock_init(&dev->lock);

二、//dev->queue = blk_alloc_queue(GFP_KERNEL);           //RM_NOQUEUE

//dev->queue = blk_init_queue(sbull_full_request, &dev->lock);     //RM_FULL

dev->queue = blk_init_queue(sbull_request, &dev->lock);          //RM_SIMPLE

(6)告知内核硬件扇区尺寸、和timer模拟的初始化

blk_queue_logical_block_size(dev->queue, hardsect_size);

init_timer(&dev->timer);

dev->timer.data = (unsigned long) dev;

dev->timer.function = sbull_invalidate;gendisk初始化 

一、初始化gendisk:

dev->gd = alloc_disk(SBULL_MINORS);

二、 初始化gendisk的成员

dev->gd->major = sbull_major;

dev->gd->first_minor = which*SBULL_MINORS;

dev->gd->fops = &sbull_ops;

dev->gd->queue = dev->queue;

dev->gd->private_data = dev;

(7)设置gendisk容量为xxx_size个扇区大小 

set_capacity(dev->gd  , nsectors*(hardsect_size / KERNEL_SECTOR_SIZE));

(8)剩下的就是为devices_operation结构体里声明的那些接口进行实现:

.open = sbull_open,

.release = sbull_release,

.media_changed   = sbull_media_changed,

.revalidate_disk = sbull_revalidate,

.ioctl= sbull_ioctl,

.getgeo= sbull_getgeo,

一、sbull_open(struct block_device *bdev,fmode_t mode )

二、sbull_release(struct gendisk *bd_disk, fmode_t mode)

三、sbull_media_changed(struct gendisk *gd)

四、sbull_revalidate(struct gendisk *gd)

五、sbull_invalidate(unsigned long ldev)

六、sbull_ioctl (struct block_device *bdev, fmode_t mode,

                   unsigned int cmd, unsigned long arg)

七、sbull_getgeo(struct block_device *bdev, struct hd_geometry *geo)

以下是代码:

[cpp]viewplaincopyprint?

1./* 

2. * Sample disk driver for 2.6.35. 

3. */  

4.  

5.//#include   

6.#include   

7.#include   

8.#include   

9.  

10.#include   

11.#include  /* printk() */  

12.#include        /* kmalloc() */  

13.#include      /* everything... */  

14.#include   /* error codes */  

15.#include   

16.#include   /* size_t */  

17.#include   /* O_ACCMODE */  

18.#include   /* HDIO_GETGEO */  

19.#include   

20.#include   

21.#include   

22.#include   

23.#include     /* invalidate_bdev */  

24.#include   

25.  

26.MODULE_LICENSE("Dual BSD/GPL");  

27.  

28.static int sbull_major = 0;  

29.module_param(sbull_major, int, 0);  

30.static int hardsect_size = 512;  

31.module_param(hardsect_size, int, 0);  

32.static int nsectors = 25600;    /* How big the drive is */  

33.module_param(nsectors, int, 0);  

34.static int ndevices = 1;  

35.module_param(ndevices, int, 0);  

36.  

37./* 

38. * The different "request modes" we can use. 

39. */  

40.enum {  

41.    RM_SIMPLE  = 0, /* The extra-simple request function */  

42.    RM_FULL    = 1, /* The full-blown version */  

43.    RM_NOQUEUE = 2, /* Use make_request */  

44.};  

45.//static int request_mode = RM_FULL;  

46.//static int request_mode = RM_SIMPLE;  

47.static int request_mode = RM_NOQUEUE;  

48.module_param(request_mode, int, 0);  

49.  

50./* 

51. * Minor number and partition management. 

52. */  

53.#define SBULL_MINORS    16  

54.#define MINOR_SHIFT 4  

55.#define DEVNUM(kdevnum) (MINOR(kdev_t_to_nr(kdevnum)) >> MINOR_SHIFT  

56.  

57./* 

58. * We can tweak our hardware sector size, but the kernel talks to us 

59. * in terms of small sectors, always. 

60. */  

61.#define KERNEL_SECTOR_SIZE  512  

62.  

63./* 

64. * After this much idle time, the driver will simulate a media change. 

65. */  

66.#define INVALIDATE_DELAY    60*HZ  

67.  

68./* 

69. * The internal representation of our device. 

70. */  

71.struct sbull_dev {  

72.        int size;                       /* Device size in sectors */  

73.        u8 *data;                       /* The data array */  

74.        short users;                    /* How many users */  

75.        short media_change;             /* Flag a media change?

 */  

76.        spinlock_t lock;                /* For mutual exclusion */  

77.        struct request_queue *queue;    /* The device request queue */  

78.        struct gendisk *gd;             /* The gendisk structure */  

79.        struct timer_list timer;        /* For simulated media changes */  

80.};  

81.  

82.static struct sbull_dev *Devices = NULL;  

83.  

84./* 

85. * Handle an I/O request. 

86. */  

87.static void sbull_transfer(struct sbull_dev *dev, unsigned long sector,  

88.        unsigned long nsect, char *buffer, int write)  

89.{  

90.    unsigned long offset = sector*KERNEL_SECTOR_SIZE;  

91.    unsigned long nbytes = nsect*KERNEL_SECTOR_SIZE;  

92.    //printk("<0>""in %s offset=%d  nbytes=%d write=%d\n",__FUNCTION__,offset,nbytes,write);  

93.    //buffer[10]='\0';  

94.    //printk(buffer);  

95.    //printk("\n");  

96.    if ((offset + nbytes) > dev->size) {  

97.        printk (KERN_NOTICE "Beyond-end write (%ld %ld)\n", offset, nbytes);  

98.        return;  

99.    }  

100.    if (write)  

101.        memcpy(dev->data + offset, buffer, nbytes);  

102.    else  

103.        memcpy(buffer, dev->data + offset, nbytes);  

104.}  

105.  

106./*The simple form of the request function.*/  

107.  

108.static void sbull_request(struct request_queue *q)  

109.{  

110.    struct request *req;  

111.  

112.    req = blk_fetch_request(q);  

113.    while (req  !

= NULL) {  

114.        struct sbull_dev *dev = req->rq_disk->private_data;  

115.        if (!

 blk_fs_request(req)) {  

116.            printk (KERN_NOTICE "Skip non-fs request\n");  

117.            __blk_end_request_all(req, -EIO);  

118.            continue;  

119.        }  

120.    //      printk (KERN_NOTICE "Req dev %d dir %ld sec %ld, nr %d f %lx\n",  

121.    //              dev - Devices, rq_data_dir(req),  

122.    //              req->sector, req->current_nr_sectors,  

123.    //              req->flags);  

124.    //  printk("sectors=%d\n",req->current_nr_sectors);  

125.        sbull_transfer(dev, blk_rq_pos(req), blk_rq_cur_sectors(req),  

126.                req->buffer, rq_data_dir(req));  

127.        if ( !

 __blk_end_request_cur(req, 0) ) {  

128.            req = NULL;  

129.        }  

130.    }  

131.}  

132.  

133.  

134./* 

135. * Transfer a single BIO. 

136. */  

137.static int sbull_xfer_bio(struct sbull_dev *dev, struct bio *bio)  

138.{  

139.    int i;  

140.    struct bio_vec *bvec;  

141.    sector_t sector = bio->bi_sector;  

142.  

143.    /* Do each segment independently. */  

144.    bio_for_each_segment(bvec, bio, i) {  

145.        char *buffer = __bio_kmap_atomic(bio, i, KM_USER0);  

146.        sbull_transfer(dev, sector, bio_cur_bytes(bio)>>9 ,  

147.                buffer, bio_data_dir(bio) == WRITE);  

148.        sector += bio_cur_bytes(bio)>>9;  

149.        __bio_kunmap_atomic(bio, KM_USER0);  

150.    }  

151.    return 0; /* Always "succeed" */  

152.}  

153.  

154./* 

155. * Transfer a full request. 

156. */  

157.static int sbull_xfer_request(struct sbull_dev *dev, struct request *req)  

158.{  

159.    struct bio *bio;  

160.    int nsect = 0;  

161.      

162.    __rq_for_each_bio(bio, req) {  

163.        sbull_xfer_bio(dev, bio);  

164.        nsect += bio->bi_size/KERNEL_SECTOR_SIZE;  

165.    }  

166.    return nse

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 育儿知识

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1