2017-11-15 2 views
0

Linux 커널 3.10.14의 사용자 공간에서 I2C 장치 드라이버 노드에 액세스하려고합니다. 커널 설정에서 i2c-dev를 추가했고/dev/i2c- * 디바이스 노드를 얻었다. 그러나 자신이 갖고있는 권한 드라이버/I2C/I2C-dev.c에서 나는 콜백 드라이버 코드에서 장치 권한 설정에 실패했습니다.

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; 
} 

과 동일한 파일에 내가 디바이스 클래스 구조체에 콜백 추가

추가
$ 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

이렇게해도 장치 파일의 사용 권한은 변경되지 않았습니다. 그것은로서 사용된다 : – keepitintheground

+0

드라이버/I2C/I2C-dev.c에서 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 접근 방식이 실패합니다. 배포판이 핫 플러그를 지원하는 다른 방법을 사용하고있을 수 있으므로 해당 배포판에 대한 설명서를 참조해야합니다.