文章类型: ANDROID
关键词: ueventd.rc,处理硬件设备权限和android,init,对其解析
内容摘要: ueventd.rc 处理硬件设备权限和android init 对其解析

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

2017/4/19 10:20:37    来源:apple    阅读:

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


↑ 上一篇文章:总结android模拟器使用PC的串口调试程序的完整过程 关键词:总结android模拟器使用PC的串口调试程序的完整过程 发布日期:2017/4/19 10:04:58
↓ 下一篇文章:Android串口调试 关键词:Android串口调试 发布日期:2017/4/19 10:21:55
相关文章:
在应用程序级别以外使用注册为 allowDefinition=MachineToApplication的节是错误的解决办法 关键词:在应用程序级别以外使用注册为,allowDefinition=MachineToApplicat.. 发布日期:2017-09-28 20:30
相关目录:.NETANDROIDJAVA软件开发
我要评论
正在加载评论信息......