13

注:この問題を現在の状態でリストしています。実装を変更すること (たとえば、クラスの作成を共通領域に移動すること) に反対しているわけではありません。どうやってするの。:エンドノート

2 つの Linux カーネル モジュールがあり、それらの /sys エントリを更新しようとしています。Google やその他のソースを検索すると、次の行に沿って多くのコードが表示されます。

static dev_t MyDev;
static struct class *c1;

static int __init start_func(void)
{
    ...
    MyDev = MKDEV(nMajor, MINOR_VERSION);
    register_chrdev_region(MyDev, 1, MODULE_NAME);
    c1 = class_create(THIS_MODULE, "chardrv");
    device_create(c1, NULL, MyDev, NULL, MODULE_NAME);
    ....

そして、最初のモジュールでこのコードが機能し、正しく作成されることを確認しました:

/sys/class/chardrv/<MODULE_NAME>

エントリ。私が知りたいのは、既存のクラスでデバイスを作成する方法です。つまり、私のモジュールの 1 つがこの新しい chardrv クラスを作成しました。今度は、他のモジュールも同じクラスの下にそのデバイスを登録できるようにしたいと考えています。

その「chardrv」クラスが既に存在するため、(2 番目のモジュールで) class_create() を再度呼び出すことはできません...

したがって、チェックを実行して /sys/class/chardrv が存在するかどうかを確認できます。これは、class_create() を呼び出す必要があるかどうかを判断するのに役立ちます。それは問題ではありません。明確にするために、ここにいくつかの疑似コードを入れてみましょう。

if ( path "/sys/class/chardrv" does not exist)
    new_class = class_create("chardrv")
else
    new_class = some how get class "chardrv" handle, or properties, or whatever
device_create(new_class, ...)

したがって、この例のように、クラスが既に存在し、新しいデバイスを2 番目のモジュールから追加したい場合は、クラス構造を作成し、何らかの方法で正しい「chardrv クラス」属性を設定して呼び出す必要があると想定します。前と同じように device_create を作成しましたが、その方法がわかりません。

4

4 に答える 4

3

device_create()サンプルコードに従うには、同じクラスを渡してもう一度呼び出すだけです。

MyDev = MKDEV(nMajor, MINOR_VERSION);
register_chrdev_region(MyDev, 1, MODULE_NAME);
c1 = class_create(THIS_MODULE, "chardrv");
device_create(c1, NULL, MyDev, NULL, MODULE_NAME);
...
device_create(c1, NULL, MyDev2, NULL, "mydev2");

クラスが作成されたかどうかを判断するために、パスを確認する必要はまったくありません。コードで作成しているので、必要に応じてフラグをテストするc1 == NULLか使用してください。

于 2012-08-16T23:37:24.490 に答える
-1

Linux カーネルはそれを許可しません。これはあなたが得るエラーです。

**[  865.687824] kobject_add_internal failed for net with -EEXIST, don't try to register things with the same name in the same directory.  
[  865.687835] Pid: 6382, comm: insmod Tainted: P        W  O 3.2.16.1JeshuLinux #1  
[  865.687840] Call Trace:  
[  865.687849]  [<c1584382>] ? printk+0x2d/0x2f  
[  865.687859]  [<c12a5438>] kobject_add_internal+0x138/0x1d0  
[  865.687869]  [<c12a5a11>] kset_register+0x21/0x50  
[  865.687879]  [<c137b63d>] __class_register+0xcd/0x1b0  
[  865.687888]  [<f8d0a0aa>] hello_init+0x4a/0x80 [sysfs_Dev]  
[  865.687897]  [<c1003035>] do_one_initcall+0x35/0x170    
[  865.687909]  [<f8d0a060>] ? enable_show+0x40/0x40 [sysfs_Dev]    
[  865.687919]  [<c10928d0>] sys_init_module+0x2c0/0x1b50    
[  865.687941]  [<c159485f>] sysenter_do_call+0x12/0x28    
[  865.687947] Registering Class Failed**  

If you want to understand sysfs read: [mochel.pdf](www.kernel.org/pub/linux/kernel/people/mochel/doc/papers/ols-2005/mochel.pdf)
于 2012-08-16T19:15:45.757 に答える