在insmod之后,我无法在/ proc / devices中看到设备条目

时间:2012-05-08 14:05:36

标签: linux-kernel device-driver

执行命令“insmod demo_device”后,在/ proc / modules

中列出了模块
**demo_device 2528 0 - Live 0xe02da000**
fp_indicators 5072 1 - Live 0xe02d2000 (P)
screader 22672 1 - Live 0xe02c5000 (P)
icamdescrambler 12912 0 - Live 0xe02b2000 (P)
icamemmfilter 16208 0 - Live 0xe02a4000 (P)
icamecmfilter 14992 0 - Live 0xe0294000 (P)
但是“(P)”之后无济于事。

在触发命令cat /proc/devices后,设备“demo_device”未列在那里。

所以我的问题是:(P)代表什么(cat /proc/modules)以及设备未列在(cat /proc/devices)中的原因可能是什么。

先谢谢!!

源代码如下:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
#include "query_ioctl.h"

#define FIRST_MINOR 0
#define MINOR_CNT 1

static dev_t dev;
static struct cdev c_dev;
static struct class *cl;
static int status = 1, dignity = 3, ego = 5;

static int my_open(struct inode *i, struct file *f)
{
    return 0;
}
static int my_close(struct inode *i, struct file *f)
{
    return 0;
}
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
static int my_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
#else
static long my_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
#endif
{
    query_arg_t q;

    switch (cmd)
    {
        case QUERY_GET_VARIABLES:
            q.status = status;
            q.dignity = dignity;
            q.ego = ego;
            if (copy_to_user((query_arg_t *)arg, &q, sizeof(query_arg_t)))
            {
                return -EACCES;
            }
            break;
        case QUERY_CLR_VARIABLES:
            status = 0;
            dignity = 0;
            ego = 0;
            break;
        case QUERY_SET_VARIABLES:
            if (copy_from_user(&q, (query_arg_t *)arg, sizeof(query_arg_t)))
            {
                return -EACCES;
            }
            status = q.status;
            dignity = q.dignity;
            ego = q.ego;
            break;
        default:
            return -EINVAL;
    }

    return 0;
}

static struct file_operations query_fops =
{
    .owner = THIS_MODULE,
    .open = my_open,
    .release = my_close,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
    .ioctl = my_ioctl
#else
    .unlocked_ioctl = my_ioctl
#endif
};

static int __init query_ioctl_init(void)
{
    int ret;
    struct device *dev_ret;

    printk("Before calling alloc\n");
    dev=150;
    if ((ret = register_chrdev_region(dev, MINOR_CNT, "demo_device")))
    {
        return ret;
    }
    else if((ret = alloc_chrdev_region(&dev,0,MINOR_CNT,"demo_device")))
    {
        return ret;
    }
    printk("After alloc %d %d\n",ret,dev);


    cdev_init(&c_dev, &query_fops);

    if ((ret = cdev_add(&c_dev, dev, MINOR_CNT)) < 0)
    {
        return ret;
    }
    printk("After cdev_add\n");

    if (IS_ERR(cl = class_create(THIS_MODULE, "char")))
    {
        cdev_del(&c_dev);
        unregister_chrdev_region(dev, MINOR_CNT);
        return PTR_ERR(cl);
    }
    printk("After class_create\n");

    if (IS_ERR(dev_ret = device_create(cl, NULL, dev, NULL, "demo")))
    {
        class_destroy(cl);
        cdev_del(&c_dev);
        unregister_chrdev_region(dev, MINOR_CNT);
        return PTR_ERR(dev_ret);
    }
    printk("After device_create\n");


    return 0;
}

static void __exit query_ioctl_exit(void)
{
    device_destroy(cl, dev);
    class_destroy(cl);
    cdev_del(&c_dev);
    unregister_chrdev_region(dev, MINOR_CNT);
}

module_init(query_ioctl_init);
module_exit(query_ioctl_exit);

MODULE_LICENSE("GPL");

插入模块后,我可以看到这些消息:

$ insmod demo_device.ko
在调用alloc之前 分配后0 217055232
在cdev_add之后 在class_create之后 在device_create之后 $

3 个答案:

答案 0 :(得分:0)

查看kernel / module.c中的module_flags_taint()

'P'标志仅表示其他模块是专有的。您的设备未显示在/proc/devices中的原因可能是因为初始化出现问题,但除非您向我们展示,否则我们无法帮助您。

答案 1 :(得分:0)

执行完成后,清理linux /应用程序源代码并重新构建它...让它工作。现在插入模块后,相应的条目在/ proc / devcies文件中是visibe:)

答案 2 :(得分:0)

确保设备的主要号码不被其他设备文件占用。使用以下命令检查占用的主要号码

   cat /proc/devices

使用以下代码捕获init函数中的初始化错误

   int t=register_chrdev(majorNumber,"mydev",&fops);

   if(t<0)
   printk(KERN_ALERT "device registration failed.");

使用 dmesg 查看内核日志