ueventd.rc 处理硬件设备权限和android init 对其解析

来源:互联网 发布:xampp mysql 配置文件 编辑:程序博客网 时间:2024/05/16 17:02
 

ueventd.rc 处理硬件设备权限和android init 对其解析


Ueventd.rc对硬件设备访问权限处理

ueventd.rc

---------------------------------------------------------

/dev/null                 0666   root       root
/dev/zero                 0666   root       root
/dev/full                 0666   root       root
/dev/ptmx                 0666   root       root
/dev/tty                  0666   root       root
/dev/random               0666   root       root
/dev/urandom              0666   root       root
/dev/ashmem               0666   root       root
/dev/binder               0666   root       root

# logger should be world writable (for logging) but not readable
/dev/log/*                0662   root       log

# the msm hw3d client device node is world writable/readable.
/dev/msm_hw3dc            0666   root       root

# gpu driver for adreno200 is globally accessible
/dev/kgsl                 0666   root       root


/dev/graphics/*           0660   root       graphics
/dev/msm_hw3dm            0660   system     graphics
/dev/input/*              0660   root       input
/dev/eac                  0660   root       audio
/dev/cam                  0660   root       camera
/dev/pmem                 0660   system     graphics
/dev/pmem_adsp*           0660   system     audio
/dev/pmem_camera*         0660   system     camera
/dev/oncrpc/*             0660   root       system
/dev/adsp/*               0660   system     audio
/dev/snd/*                0660   system     audio
/dev/mt9t013              0660   system     system
/dev/msm_camera/*         0660   system     system
/dev/msm_pcm_in*          0660   system     audio
/dev/msm_pcm_ctl*         0660   system     audio
/dev/msm_snd*             0660   system     audio
/dev/msm_mp3*             0660   system     audio
/dev/audience_a1026*      0660   system     audio
/dev/tpa2018d1*           0660   system     audio
/dev/msm_audpre           0660   system     audio
/dev/msm_audio_ctl        0660   system     audio
/dev/htc-acoustic         0660   system     audio
/dev/vdec                 0660   system     audio
/dev/q6venc               0660   system     audio
/dev/snd/dsp              0660   system     audio
/dev/snd/dsp1             0660   system     audio
/dev/snd/mixer            0660   system     audio
/dev/smd0                 0640   radio      radio
/dev/qmi                  0640   radio      radio
/dev/qmi0                 0640   radio      radio
/dev/qmi1                 0640   radio      radio
/dev/qmi2                 0640   radio      radio
/dev/bus/usb/*            0660   root       usb
/dev/mtp_usb              0660   root       mtp
/dev/usb_accessory        0660   root       usb
/dev/tun                  0660   system     vpn
/dev/video*               0666   root       root

工作遇到打开/dev/video0失败的问题,在ueventd.rc中添加一行 /dev/video*               0666   root       root 就OK 啦

下面介绍android init 对其解析与启动

 

 Android的每个目录下面都有一个非常重要的文件Android.mk,负责编译该目录下面的代码。

 

System/core/init/android.mk


LOCAL_MODULE:= init

LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)

LOCAL_STATIC_LIBRARIES := libcutils libc

 

上面的代码会生成一个叫init的可执行程序,它会被放在/下面,且同时    会产生一个符号链接/sbin/eventd,指向/init. 我们不禁要问,为什么这样做?

      Init是一个脚本解释器,它会对目标系统下的两个文件解析,

     /init.rc

     /init.xxx.rc (xxx代表平台平台名)

     先看看源代码目录/device/xxx/init.rc

service ueventd /sbin/ueventd
    class core
    critical

 

   看来init在解析脚本的时候又启动了一个自己的进程,只是进程名变成了ueventd.

     System/core/init/init.c/main

 

    if (!strcmp(basename(argv[0]), "ueventd"))
        return ueventd_main(argc, argv);

 

根据进程名不同,程序执行路径不同。Ueventd顾名思义应该是接收uvent的守护进程,这里它的主要作用根据uevent是创建或删除/dev/xxx(xxx设备名),我们知道在linux下面创建设备节点的接口mknod,我们跟进去看看这个接口是在哪里调用的

     System/core/init/Ueventd.c/ueventd_main


    get_hardware_name(hardware, &revision);

    ueventd_parse_config_file("/ueventd.rc");

    snprintf(tmp, sizeof(tmp), "/ueventd.%s.rc", hardware);
    ueventd_parse_config_file(tmp);

    device_init();

    ufd.events = POLLIN;
    ufd.fd = get_device_fd();

 

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

    system/core/rootdir/ueventd.rc 

eg>  /dev/binder  

 

 这里请注意,ueventd_parse_config_file并不创建设备节点,它的作用是提供数据库,当有设备节点生成的时候,eventd会参考这个数据库设置设备节点的权限。

    

      system/core/init/devices.c/device_init

 

   device_fd = uevent_open_socket(64*1024, true);
    if(device_fd < 0)
        return;

    fcntl(device_fd, F_SETFD, FD_CLOEXEC);
    fcntl(device_fd, F_SETFL, O_NONBLOCK);

    if (stat(coldboot_done, &info) < 0) {
        t0 = get_usecs();
        coldboot("/sys/class");
        coldboot("/sys/block");
        coldboot("/sys/devices");
        t1 = get_usecs();
        fd = open(coldboot_done, O_WRONLY|O_CREAT, 0000);
        close(fd);
        log_event_print("coldboot %ld uS\n", ((long) (t1 - t0)));
    } else {
        log_event_print("skipping coldboot, already done\n");
    }

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

 

 

   ufd.events = POLLIN;
    ufd.fd = get_device_fd();

    while(1) {
        ufd.revents = 0;
        nr = poll(&ufd, 1, -1);
        if (nr <= 0)
            continue;
        if (ufd.revents == POLLIN)
               handle_device_fd();
    }

 

  死循环,接受kernel传过来的uevent,动态创建或删除节点.

      handle_device_fd会最终调用mknod创建设备节点,流程如下:

      handle_device_fd-> handle_device_event-> make_device-> mknod

0 0
原创粉丝点击