Tiny6410开发板下块设备驱动程序的编写驱动之用内存模拟磁盘(一)

来源:互联网 发布:阿城 作家 知乎 编辑:程序博客网 时间:2024/06/07 09:27

开发平台:友善Tiny6410开发板 内核版本linux-2.6.38

参考韦东山老师二期视频

1th : 驱动程序框架




/* 参考:
 * drivers\block\xd.c
 * drivers\block\z2ram.c
 */
 
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/genhd.h>
#include <linux/hdreg.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/blkdev.h>
#include <linux/mutex.h>
#include <linux/blkpg.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/gfp.h>


#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/dma.h>


static struct gendisk *ramblock_disk;
struct request_queue *ramblock_queue;
static int major;


static DEFINE_SPINLOCK(ramblock_lock);


static const struct block_device_operations ramblock_fops = {
.owner = THIS_MODULE,
};


#define RAMBLOCK_SIZE (1024*1024)


static void do_ramblock_request (struct request_queue * q)
{
static int cnt = 0;

printk("do_ramblock_request %d\n",++cnt);
}
static int ramblock_init(void)
{
/* 1. 分配一个gendisk结构体 */
ramblock_disk = alloc_disk(16);    /* 次设备号个数: 分区个数+1 */

/* 2. 设置 */
/* 2.1 分配/设置队列: 提供读写能力 */
ramblock_queue = blk_init_queue(do_ramblock_request, &ramblock_lock);
ramblock_disk->queue = ramblock_queue;

/* 2.2 设置其他属性: 比如容量 */
major = register_blkdev(0, "ramblock");   /* cat /proc/devices */

ramblock_disk->major           = major;
ramblock_disk->first_minor = 0;
sprintf(ramblock_disk->disk_name, "ramblock");
ramblock_disk->fops = &ramblock_fops;

set_capacity(ramblock_disk, RAMBLOCK_SIZE / 512);

/* 3. 注册 */
add_disk(ramblock_disk);
return 0;
}


static void ramblock_exit()
{
unregister_blkdev(major, "ramblock");
del_gendisk(ramblock_disk);
put_disk(ramblock_disk);
blk_cleanup_queue(ramblock_queue);
}

module_init(ramblock_init);
module_exit(ramblock_exit);

测试1th  此时由于do_ramblock_request() 函数没有做任何操作,加载模块后没有返回


2th

要参照自己的linux内核源代码来改动韦老师的驱动程序,主要是改动do_ramblock_request()函数

韦老师代码:

static void do_ramblock_request(request_queue_t * q)
{
static int cnt = 0;
struct request *req;

printk("do_ramblock_request %d\n", ++cnt);

while ((req = elv_next_request(q)) != NULL) {
end_request(req, 1);
}
}

改动之后:

static void do_ramblock_request (struct request_queue * q)
{
static int cnt = 0;
struct request *req;


printk("do_ramblock_request %d\n",++cnt);


req = blk_fetch_request(q);
while(req)
{
/* wrap up, 0 = success, -errno = fail */
if (!__blk_end_request_cur(req, 0))
req = blk_fetch_request(q);
}
将elv_next_request()改成blk_fetch_request() ; end_request(req,1)改成blk_end_request_cur(req,0)


此时可以正常退出


0 0
原创粉丝点击