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