0

执行命令“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
后 alloc 0 217055232
后 cdev_add
后 class_create
后 device_create
$

4

3 回答 3

0

查看module_flags_taint()kernel/module.c。

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

于 2012-05-08T17:44:56.897 回答
0

在对 linux/应用程序源代码执行 make clean 并再次重建它之后......让它工作。现在插入模块后,相应的条目在 /proc/devcies 文件中可见:)

于 2012-05-11T07:56:09.827 回答
0

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

   cat /proc/devices

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

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

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

使用dmesg查看内核日志

于 2016-06-22T05:23:46.873 回答