2017-11-15 43 views
0

LinuxカーネルのユーザスペースからI2Cデバイスドライバノードにアクセスしたい3.10.14。 カーネル構成でi2c-devを追加し、/ dev/i2c- *デバイスノードを取得しました。しかし、彼らは私がコールバックにドライバコードからのデバイス許可の設定に失敗しました

static char *i2c_dev_devnode(struct device *dev, umode_t *mode) 
{ 
    if (!mode) 
      return NULL; 
    if (MAJOR(dev->devt) == I2C_MAJOR) 
      *mode = 0666; 
    return NULL; 
} 

と同じファイル内に追加の許可ドライバ/ I2C/I2C-dev.cで

$ ls -l /dev/i2c-* 
crw------- root  root  89, 1 2014-08-21 20:00 i2c-1 

を持っている私は、デバイスのクラス構造体へのコールバックを追加しました:

デバイスノードのアクセス権が残っしかし

static int __init i2c_dev_init(void) 
{ 
    ... 
    i2c_dev_class = class_create(THIS_MODULE, "i2c-dev"); 
    ... 

    /* set access rights */ 
    i2c_dev_class->devnode = i2c_dev_devnode; 
    ... 
} 

crw------- root  root  89, 1 2014-08-21 20:00 i2c-1 

/lib/udev/rules.dや/etc/udev/rules.dはありません

ここで間違っているかもしれない何か提案がありましたら幸いです。

私はこのアイデアをテストする方法にも興味があります。

答えて

0

私はdevnodeコールバック関数の戻り値が "NULL"ではなくデバイスノード名であることを理解しています。 したがって、 関数の戻り値を "NULL"からdevnameに変更します。コードを参照してください:

----------------------パッチ------------------- -

diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c 
index 6f638bb..35a42c6 100644 
--- a/drivers/i2c/i2c-dev.c 
+++ b/drivers/i2c/i2c-dev.c 
@@ -614,6 +614,14 @@ static int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action, 
    .notifier_call = i2cdev_notifier_call, 
}; 

+static char *i2c_dev_devnode(struct device *dev, umode_t *mode) 
+{ 
+ printk("\n\n****%s: %d\n\n",__func__,__LINE__); 
+ if (mode != NULL) 
+   *mode = 0666; 
+ return kasprintf(GFP_KERNEL, "i2cr/%s", dev_name(dev));; 
+} 
+ 
/* ------------------------------------------------------------------------- */ 

/* 
@@ -636,7 +644,12 @@ static int __init i2c_dev_init(void) 
     goto out_unreg_chrdev; 
    } 
    i2c_dev_class->dev_groups = i2c_groups; 
+ /* set access rights */ 
+ printk(KERN_INFO "i2c setting devnode\n"); 
+ i2c_dev_class->devnode = i2c_dev_devnode; 
+ 

+ 
    /* Keep track of adapters which will be added or removed later */ 
    res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier); 
    if (res) 

結果: このパッチを適用せず:

[email protected]:~# ls -l /dev/i2c-* 
crw------- 1 root root 89, 0 Nov 1 13:47 /dev/i2c-0 
crw------- 1 root root 89, 1 Nov 1 13:47 /dev/i2c-1 

パッチ付:

[email protected]:~# ls -l /dev/i2cr/*  
crw-rw-rw- 1 root root 89, 0 Nov 1 13:38 /dev/i2cr/i2c-0 
crw-rw-rw- 1 root root 89, 1 Nov 1 13:38 /dev/i2cr/i2c-1 

+0

これは、デバイスファイルのアクセス許可を変更しませんでした。ドライバ/ I2C/I2C-dev.cにおいて – keepitintheground

+0

Iはまた、デバイスを定義するためのヘルパーマクロDEVICE_ATTR属性が見つかりました: それは次のように使用されている: 静的DEVICE_ATTR(FOO、S_IRUGO、show_foo、store_foo)。 したがって、/ dev/i2c- *のパーミッションはcr-r-r-- でなければなりません。 – keepitintheground

+0

私はあなたのためにこれをテストしました。これは完全に機能します。パッチ&テストの下に置く。 – rk1825

0

次の方法をお試しください。これは少なくともカーネル4.9.56で動作します。

static int my_uevent(struct device *dev, struct kobj_uevent_env *env) 
{ 
    add_uevent_var(env, "DEVMODE=%#o", 0666); 
    return 0; 
} 

static int __init i2c_dev_init(void) 
{ 
    ... 
    i2c_dev_class = class_create(THIS_MODULE, "i2c-dev"); 
    ... 

    /* set access rights */ 
    i2c_dev_class->dev_uevent = my_uevent; 
    ... 
} 
0

デバイスノードの設定は、udevの責任で行ってください。正しいudevルールを使用する必要があります。ブート可能な時間の後にドライバがロードされた場合、例えばロード可能なモジュールの場合には、init.rcのさらなるアプローチが失敗します。あなたのディストリビューションはhotplugをサポートする別の方法を使用しているかもしれないので、そのディストリビューションに関するドキュメントを参照する必要があります。

関連する問題