Ueventd.rc handles hardware device access permissions

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

The work encounters the problem of failure to open /dev/video0, add a line /dev/video* 0666 root root in ueventd.rc and it will be OK

The following introduces the analysis and startup of android init

 

 There is a very important file Android.mk under each directory of Android, which is responsible for compiling the code under the directory.

 

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

 

The above code will generate an executable program called init, which will be placed under /, and will also generate a symbolic link /sbin/eventd, pointing to /init. We can't help but ask, why do this?

      Init is a script interpreter that parses two files under the target system,

     /init.rc

     /init.xxx.rc (xxx represents the platform platform name)

     First look at the source code directory /device/xxx/init.rc

service ueventd /sbin/ueventd
    class core
    critical

 

   It seems that init starts another process of its own when parsing the script, but the process name becomes ueventd.

 

     System/core/init/init.c/main

 

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

 

Depending on the process name, the program execution path is different. Ueventd, as the name suggests, should be a daemon process that receives uvent. Its main function here is to create or delete /dev/xxx (xxx device name) according to uevent. We know the interface mknod for creating device nodes under linux. Let's follow up to see this interface where is it called

 

     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 has two scripts that need to be parsed, ueventd.rc, ueventd.xxx.rc, the script, see also the script This script allows customers to set the permissions of the /dev or /sys directory and subdirectories.

    system/core/rootdir/ueventd.rc 

eg>  /dev/binder  

 

 Please note here that ueventd_parse_config_file does not create a device node. Its role is to provide a database. When a device node is generated, eventd will refer to this database to set the permissions of the device node.

    

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

   This function is very simple. It mainly creates the socket handle of uevent, triggers the uevents in the three directories /sys/clas, /sys/block, /sys/devices and their subdirectories, and then accepts and creates device nodes. So far The device node is only created. There is a very interesting function do_coldboot in coldboot, which is a recursive calling function. The implementation is very interesting. You can take a look.

 

 

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

 

  Infinite loop, accept the uevent from the kernel, dynamically create or delete nodes.

      handle_device_fd will eventually call mknod to create a device node. The process is as follows:

      handle_device_fd-> handle_device_event-> make_device-> mknod

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325731397&siteId=291194637