首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

关于块设备驱动程序的问题1

关于块设备驱动程序的问题1

各位高手:
              小弟正在编写一个简单的块设备驱动。编译后加载该驱动,出现”insmod:cannot insert simple_block.ko’:cannot allocate memory”。请教出现此问题的原因。谢谢!驱动源码如下:
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/kernel.h>
/* printk() */

#include <linux/slab.h>
/* kmalloc() */

#include <linux/fs.h>
/* everything... */

#include <linux/errno.h>
/* error codes */

#include <linux/timer.h>
#include <linux/types.h>
/* size_t */

#include <linux/fcntl.h>
/* O_ACCMODE */

#include <linux/hdreg.h>
/* HDIO_GETGEO */

#include <linux/kdev_t.h>
#include <linux/vmalloc.h>
#include <linux/genhd.h>
#include <linux/blkdev.h>
#include <linux/buffer_head.h>
/* invalidate_bdev */

#include <linux/bio.h>

#define SIMP_BLKDEV_DEVICEMAJOR
COMPAQ_SMART2_MAJOR

#define SIMP_BLKDEV_DISKNAME
"simp_blkdev"

#define SIMP_BLKDEV_BYTES
(16*1024*1024)


unsigned char simp_blkdev_data[SIMP_BLKDEV_BYTES];

static struct request_queue *simp_blkdev_queue;
static struct gendisk *simp_blkdev_disk;

static void simp_blkdev_do_request(struct request_queue *q);

struct block_device_operations simp_blkdev_fops = {

.owner
= THIS_MODULE,

};

static void simp_blkdev_do_request(struct request_queue *q)
{

struct request *req;


while ((req = elv_next_request(q)) != NULL) {


if ((req->sector + req->current_nr_sectors) << 9


> SIMP_BLKDEV_BYTES) {


printk(KERN_ERR SIMP_BLKDEV_DISKNAME


": bad request: block=%llu, count=%u\n",


(unsigned long long)req->sector,


req->current_nr_sectors);


end_request(req, 0);


continue;


}



switch (rq_data_dir(req)) {


case READ:


memcpy(req->buffer,



simp_blkdev_data + (req->sector << 9),


req->current_nr_sectors << 9);


end_request(req, 1);


break;


case WRITE:


memcpy(simp_blkdev_data + (req->sector << 9),


req->buffer, req->current_nr_sectors << 9);


end_request(req, 1);


break;


default:


/* No default because rq_data_dir(req) is 1 bit */


break;


}


}

}

static int __init simp_blkdev_init(void)
{

int ret;



simp_blkdev_queue = blk_init_queue(simp_blkdev_do_request, NULL);


if (!simp_blkdev_queue) {


ret = -ENOMEM;


goto err_init_queue;


}

      

simp_blkdev_disk = alloc_disk(1);


if (!simp_blkdev_disk) {


ret = -ENOMEM;


goto err_alloc_disk;


}




strcpy(simp_blkdev_disk->disk_name, SIMP_BLKDEV_DISKNAME);


simp_blkdev_disk->major = SIMP_BLKDEV_DEVICEMAJOR;


simp_blkdev_disk->first_minor = 0;


simp_blkdev_disk->fops = &simp_blkdev_fops;


simp_blkdev_disk->queue = simp_blkdev_queue;


set_capacity(simp_blkdev_disk, SIMP_BLKDEV_BYTES>>9);


add_disk(simp_blkdev_disk);



return 0;


err_alloc_disk:

blk_cleanup_queue(simp_blkdev_queue);

err_init_queue:

return ret;

}

static void __exit simp_blkdev_exit(void)
{

del_gendisk(simp_blkdev_disk);


put_disk(simp_blkdev_disk);


blk_cleanup_queue(simp_blkdev_queue);

}

module_init(simp_blkdev_init);
module_exit(simp_blkdev_exit);
返回列表