在android中,init接受来自kernel的uevent消息,根据其中信息来创建设备节点。设备节点的名字由device path中最后一段(用/分开)指定,路径由subsystem决定,而权限可以在配置文件中指定。
1. 在init中打印出uevent
init中的uevent在devices.c中打印:
log_event_print("event { '%s', '%s', '%s', '%s', %d, %d }\n",
uevent->action, uevent->path, uevent->subsystem,
uevent->firmware, uevent->major, uevent->minor);
log_event_print受LOG_UEVENTS宏控制。默认LOG_UEVENTS为0,所以禁用了uevent打印。可以在log.h中启用:
#define LOG_UEVENTS 1 /* log uevent messages if 1. verbose */
uevent用INFO打印,其等级为6,因此还需要修改log_level。在init.rc中设置:
loglevel 7
log_write的行为是,如果请求的级别大于当前设置的logleve,则返回(不打印)。
2. 分析uevent
经过上面的修改后,可以看到kernel会打印出所有的uevent。在安装触屏驱动时,会有如下信息:
[ 8.505650] init: event { 'add', '/module/touchpanel_ite', 'module', '', -1, -1 }
[ 8.513340] ITE7260 Multi-touch driver
[ 8.524876] init: event { 'add', '/class/IT7260', 'class', '', -1, -1 }
[ 8.531498] init: event { 'add', '/devices/virtual/IT7260/IT7260', 'IT7260', '', 251, 0 }
[ 8.552403] usb 1-1: new full speed USB device using pxau2h-ehci and address 2
[ 8.619572] Device ID: Device Version: ROM firmware version: 0.0.0.0
[ 8.654179] Flash firmware version: 0.0.0.0
[ 8.658787] init: event { 'add', '/devices/platform/pxa2xx-i2c.3/i2c-3/3-0046/input/input4', 'input', '', -1, -1 }
[ 8.669193] input: touch_ite as /devices/platform/pxa2xx-i2c.3/i2c-3/3-0046/input/input4
[ 8.677555] init: event { 'add', '/devices/platform/pxa2xx-i2c.3/i2c-3/3-0046/input/input4/event3', 'input', '', 13, 67 }
[ 8.688572] ITE7260 multi-touch is OK. Working in interrupt mode
[ 8.694798] init: command 'insmod' r=0
[ 8.699223] init: event { 'add', '/bus/i2c/drivers/ite7260', 'drivers', '', -1, -1 }
{ 'add', '/module/touchpanel_ite', 'module', '', -1, -1 }
这应该是insmod产生的
{ 'add', '/class/IT7260', 'class', '', -1, -1 }
class_create(THIS_MODULE, "IT7260")调用产生,加入一个class
{ 'add', '/devices/virtual/IT7260/IT7260', 'IT7260', '', 251, 0 }
device_create(ite7260_class, NULL, ite7260_dev, NULL, "IT7260");这里parent为null,所以看到device path中有virtual
另外,251为预先申请的主设备号。
{ 'add', '/devices/platform/pxa2xx-i2c.3/i2c-3/3-0046/input/input4', 'input', '', -1, -1 }
{ 'add', '/devices/platform/pxa2xx-i2c.3/i2c-3/3-0046/input/input4/event3', 'input', '', 13, 67 }
i2c_add_driver(&ite7260_driver); driver binding时会调probe。probe中注册了input设备,产生这两个uevent
{ 'add', '/bus/i2c/drivers/ite7260', 'drivers', '', -1, -1 }
i2c_add_driver添加driver成功后产生的uevent
3. 创建设备节点
init收到uevent后,对于action为add/remove的uevent,会创建或删除节点。这在handle_device_event中处理:如果主设备号或次设备号无效(-1),则返回;否则会根据subsystem会在dev下不同的目录中创建设备节点。
值得一提的是创建的设备节点的权限,默认为600。如果有特殊需求,需要在/ueventd.rc或