设为首页 加入收藏

TOP

Linux 块设备驱动 实例(一)
2014-11-24 07:23:48 来源: 作者: 【 】 浏览:9
Tags:Linux 设备驱动 实例

任务:用一片虚拟地址连续的内存空间模拟一个块设备,并为其写一个驱动


/*
* Sample disk driver, from the beginning.
*/


#include
#include
#include
#include
#include
#include /* printk() */
#include /* kmalloc() */
#include /* everything... */
#include /* error codes */
#include
#include /* size_t */
#include /* O_ACCMODE */
#include /* HDIO_GETGEO */
#include
#include
#include
#include
#include /* invalidate_bdev */
#include


MODULE_LICENSE("Dual BSD/GPL");


static int sbull_major = 0;
module_param(sbull_major, int, 0);
static int hardsect_size = 512;
module_param(hardsect_size, int, 0);
static int nsectors = 25600; /* How big the drive is */
module_param(nsectors, int, 0);
static int ndevices = 1;
module_param(ndevices, int, 0);


/*
* The different "request modes" we can use.
*/
enum {
RM_SIMPLE = 0, /* The extra-simple request function */
RM_FULL = 1, /* The full-blown version */
RM_NOQUEUE = 2, /* Use make_request */
};
//static int request_mode = RM_FULL;
static int request_mode = RM_SIMPLE;
//static int request_mode = RM_SIMPLE;
module_param(request_mode, int, 0);


/*
* Minor number and partition management.
*/
#define SBULL_MINORS 16
#define MINOR_SHIFT 4
#define DEVNUM(kdevnum) (MINOR(kdev_t_to_nr(kdevnum)) >> MINOR_SHIFT


/*
* We can tweak our hardware sector size, but the kernel talks to us
* in terms of small sectors, always.
*/
#define KERNEL_SECTOR_SIZE 512


/*
* After this much idle time, the driver will simulate a media change.
*/
#define INVALIDATE_DELAY 60*HZ


/*
* The internal representation of our device.
*/
struct sbull_dev {
int size; /* Device size in sectors */
// data 是本程序模拟的块设备,是一片连续的虚拟空间
// 在初始化函数里分配的虚拟地址连续的内存空间
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 */
};


static struct sbull_dev *Devices = NULL;


/*
* Handle an I/O request.
*/
static void sbull_transfer(struct sbull_dev *dev, unsigned long sector,
unsigned long nsect, char *buffer, int write)
{
unsigned long offset = sector*KERNEL_SECTOR_SIZE; // 需要读写的扇区的偏移地址
unsigned long nbytes = nsect*KERNEL_SECTOR_SIZE; // 需要读写的字节数

if ((offset + nbytes) > dev->size) { // 判断输入参数是否合法,是否超出边界
printk (KERN_NOTICE "Beyond-end write (%ld %ld)\n", offset, nbytes);
return;
}
// 实际的读写操作
// 由于本程序是用一片连续的内存空间模拟块设备
// 所以这里对硬件(内存空间)的读写操作,就是复制内存
// 在具体点,就是下面的memcpy
// 具体的项目,需修改为具体的接口函数
if (write)
// 写
memcpy(dev->data + offset, buffer, nbytes);
else
// 读
memcpy(buffer, dev->data + offset, nbytes);
}


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


static void sbull_request(struct request_queue *q)
{
struct request *req;


// 服务完队列上的所有请求
while ((req = elv_next_request(q)) != NULL) { // elv_next_request :从队列上去一个下来
struct sbull_dev *dev = req->rq_disk->private_data;
if (! blk_fs_request(req)) {
printk (KERN_NOTICE "Skip non-fs request\n");
end_request(req, 0);
continue;
}

首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Linux下创建进程线程以及通信技术.. 下一篇脚本--Linux下清理IPC资源

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·Redis 分布式锁全解 (2025-12-25 17:19:51)
·SpringBoot 整合 Red (2025-12-25 17:19:48)
·MongoDB 索引 - 菜鸟 (2025-12-25 17:19:45)
·What Is Linux (2025-12-25 16:57:17)
·Linux小白必备:超全 (2025-12-25 16:57:14)