insmod:错误:无法插入模块:没有这样的设备

时间:2017-12-09 20:46:40

标签: c linux

我正在尝试在Linux中使用C语言实现字符设备驱动程序。 我的代码如下:

#include<linux/device.h>
#include<linux/init.h>
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/fs.h>
#include<linux/err.h>
#include<asm/uaccess.h>
#define SUCCESS 0
#define DEVICE_NAME "chardev"
#define BUF_LEN 80

MODULE_LICENSE("GPL");

static int Major;
static char msg[BUF_LEN]={0};
static short s_o_msg;
static int Device_Open = 0;
static struct class* chardevClass = NULL;
static struct device* chardevDevice = NULL;
static char *msg_Ptr;

static int device_open(struct inode *, struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);



static struct file_operations fops = {
        .read = device_read,
        .write = device_write,
        .open = device_open,
        .release = device_release
};

static int __init chardev_init(void){
    Major = register_chrdev(0, DEVICE_NAME, &fops);

    if (Major < 0) {
        printk(KERN_ALERT "Registering char device failed with %d\n", Major);
        return Major;
    }

    chardevDevice = device_create(chardevClass, NULL, MKDEV(Major,0), NULL, DEVICE_NAME);
    if (IS_ERR(chardevDevice)) {
        class_destroy(chardevClass);
        unregister_chrdev(Major, DEVICE_NAME);
        printk(KERN_ALERT
        "Failed to create the device\n");
        return PTR_ERR(chardevDevice);
    }

    printk(KERN_INFO "I was assigned major number %d. To talk to\n", Major);
    printk(KERN_INFO "the driver, create a dev file with\n");
    printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", DEVICE_NAME, Major);
    printk(KERN_INFO "Try various minor numbers. Try to cat and echo to\n");
    printk(KERN_INFO "the device file.\n");
    printk(KERN_INFO "Remove the device file and module when done.\n");

    return SUCCESS;
}

static void __exit chardev_exit(void){
    device_destroy(chardevClass, MKDEV(Major, 0));
    class_unregister(chardevClass);
    class_destroy(chardevClass);
    unregister_chrdev(Major, DEVICE_NAME);
    printk(KERN_INFO "Goodbye!\n");
}

static int device_open(struct inode *inodep, struct file *filep)
{
    static int counter = 0;

    if (Device_Open)
        return -EBUSY;

    Device_Open++;
    sprintf(msg, "I already told you %d times Hello world!\n", counter++);
    msg_Ptr = msg;
    try_module_get(THIS_MODULE);

    return SUCCESS;
}

static ssize_t device_read(struct file *filep, char *buffer, size_t length, loff_t * offset){

    int bytes_read = 0;

    if (*msg_Ptr == 0)
        return 0;

    while (length && *msg_Ptr) {

        put_user(*(msg_Ptr++), buffer++);

        length--;
        bytes_read++;
    }

    return bytes_read;
}

static int device_release(struct inode *inodep, struct file *filep)
{
    Device_Open--;

    module_put(THIS_MODULE);

    return 0;
}



static ssize_t device_write(struct file *filep, const char *buffer, size_t length, loff_t *offset){
    sprintf(msg, "%s(%zu letters)", buffer, length);
    s_o_msg = strlen(msg);
    printk(KERN_INFO "Received %zu characters from the user\n", length);
    return length;
}

module_init(chardev_init);
module_exit(chardev_exit);

然后,我用以下命令编译它,到目前为止一切看起来都很好:

obj-m := memory.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

但是当我尝试使用

运行此模块时
sudo /sbin/insmod memory.ko

我收到错误:

insmod: ERROR: Could not insert module : No such device

你能解释一下我的错误吗?如何正确运行这个模块呢?

非常感谢。

1 个答案:

答案 0 :(得分:0)

您忘记在class_create之前创建课程(device_create()),因为如果您看到

root@achal:/sys/class# ls
.. there are so many different class..

您的device也应该在one class,这就是使用class_create();创建一个课程的原因

在代码中添加以下行。

chardevClass = class_create(THIS_MODULE, "overflow");

    chardevDevice = device_create(chardevClass, NULL, MKDEV(Major,0), NULL, DEVICE_NAME);
inserting模块需要

root 模式,compilinginserting的序列和运行模块的模式为: 首先做make

root@root:~/s_flow# make

然后做insmod&amp;分析dmesg输出

 root@root:~/s_flow# insmod memory.ko
    root@root:~/s_flow# dmesg
    ..
    .. check here whether  __init chardev_init() is invoked or not

或者您也可以检查modinfo

root@root:~/s_flow# modifno memory.ko

我希望它有所帮助。