Chinaunix首页 | 论坛 | 博客
  • 博客访问: 285291
  • 博文数量: 68
  • 博客积分: 1121
  • 博客等级: 少尉
  • 技术积分: 634
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-01 09:43
文章分类
文章存档

2014年(1)

2013年(8)

2012年(37)

2011年(22)

分类: 嵌入式

2012-10-29 15:58:58

Android中设备节点动态创建之后,设备的权限控制是通过ueventd.*.rc文件,系统启动时,init进程根据ueventd.*.rc文件生成相应的配置文件ueventd_parse_config_file;启动进程ueventd,当要生成设备节点时,ueventd根据ueventd_parse_config_file设置设备节点权限!


Init是linux kernel启动的第一个进程,
理解init,对熟悉android系统非常重要。
   Android的每个目录下面都有一个非常重要的文件Android.mk,负责编译该目录下面的代码。
   System/core/init/android.mk

  1.    LOCAL_MODULE:= init

  2.    LOCAL_FORCE_STATIC_EXECUTABLE := true
  3.    LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)

  4.    include $(BUILD_EXECUTABLE)[/size][/align][align=left][size=18px]   SYMLINKS := $(TARGET_ROOT_OUT)/sbin/ueventd
  5.    $(SYMLINKS): INIT_BINARY := $(LOCAL_MODULE)
  6.    $(SYMLINKS): $(LOCAL_INSTALLED_MODULE) $(LOCAL_PATH)/Android.mk
  7. [url=home.php?mod=space&uid=430258]@echo[/url] "Symlink: $@ -> ../$(INIT_BINARY)"
  8. @mkdir -p $(dir $@)
  9. @rm -rf $@
  10. $(hide) ln -sf ../$(INIT_BINARY) $@

复制代码
上面的代码会生成一个叫init的可执行程序,它会被放在/下面,且同时    会产生一个符号链接/sbin/eventd,指向/init. 我们不禁要问,为什么这样做?
      Init是一个脚本解释器,它会对目标系统下的两个文件解析,

  1. /init.rc
  2.      /init.xxx.rc (xxx代表平台平台名)
复制代码
先看看源代码目录/device/xxx/init.rc

  1.   on early-init
  2.      start ueventd
  3.   
复制代码
看来init在解析脚本的时候又启动了一个自己的进程,只是进程名变成了ueventd.
     
     System/core/init/init.c/main

  1.   if (!strcmp(basename(argv[0]), "ueventd"))
  2.         return ueventd_main(argc, argv);
  3.   
复制代码
根据进程名不同,程序执行路径不同。Ueventd顾名思义应该是接收uvent的守护进程,这里它的主要作用根据uevent是创建或删除/dev/xxx(xxx设备名),我们知道在linux下面创建设备节点的接口mknod,我们跟进去看看这个接口是在哪里调用的
      
     System/core/init/Ueventd.c/ueventd_main

  1.    ueventd_parse_config_file("/ueventd.rc");
  2.   snprintf(tmp, sizeof(tmp), "/ueventd.%s.rc", hardware);
  3.   ueventd_parse_config_file(tmp);
  4.   device_init();

复制代码
ueventd有两个脚本需要解析,ueventd.rc,ueventd.xxx.rc,脚本,又见脚本这个脚本可以让客户设置/dev 或 /sys目录及子目录的权限.
    system/core/rootdir/ueventd.rc

  1.   /dev/binder               0666   root       root
复制代码
这里请注意,ueventd_parse_config_file并不创建设备节点,它的作用是提供数据库,当有设备节点生成的时候,eventd会参考这个数据库设置设备节点的权限。
     
      system/core/init/devices.c/device_init

  1.     device_fd = open_uevent_socket();
  2.    coldboot("/sys/class");
  3.    coldboot("/sys/block");
  4.    coldboot("/sys/devices");

复制代码
这个函数很简单,主要是创建了uevent的socket handle,同时触发/sys/clas,/sys/block,/sys/devices这三个目录及其子目录下的uevent,然后接受并创建设备节点,至此设备节点才算创建,coldboot里面有个很有意思的函数do_coldboot,这是一个递归调用函数,实现的很有意思,大家可以看看.
       
     system/core/init/Ueventd.c/ueventd_main

  1.   while(1) {
  2.         ufd.revents = 0;
  3.         nr = poll(&ufd, 1, -1);
  4.         if (nr <= 0)
  5.             continue;
  6.         if (ufd.revents == POLLIN)
  7.                handle_device_fd();
  8.     }

复制代码
死循环,接受kernel传过来的uevent,动态创建或删除节点.
handle_device_fd会最终调用mknod创建设备节点,流程如下:

  1. handle_device_fd-> handle_device_event-> make_device-> mknod
复制代码

参考:

阅读(6073) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~