wangxd5429
驱动牛犊
驱动牛犊
  • 注册日期2005-05-12
  • 最后登录2019-08-19
  • 粉丝0
  • 关注0
  • 积分-257分
  • 威望268点
  • 贡献值0点
  • 好评度22点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:1509回复:0

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

楼主#
更多 发布于:2011-07-12 10:54

各位高手:
              小弟正在编写一个简单的块设备驱动。编译后加载该驱动,出现”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);
游客

返回顶部