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

Linux /アプリケーションのソースコードをクリーンアップして再構築した後、動作させます。モジュールを挿入した後、対応するエントリは/ proc/devciesファイルに表示されます:)

于 2012-05-11T07:56:09.827 に答える
0

module_flags_taint()kernel/module.cを見てください。

「P」フラグは、他のモジュールが独自仕様であることを示しているにすぎません。デバイスが表示されない理由は、おそらく初期化に問題があるためですが、コード/proc/devicesを表示しない限り、それを支援することはできません。

于 2012-05-08T17:44:56.897 に答える
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 に答える