基于goldfish和android2.3.5学习之:开天辟地Android启动机制[三]
***************************************************************************************************************************
作者:EasyWave 时间:2012.08.01
类别:Android系统源码分析 声明:转载,请保留链接
注意:如有错误,欢迎指正。这些是我学习的日志文章......
***************************************************************************************************************************
在我的博文基于goldfish和android2.3.5学习之:开天辟地Android启动机制[二]中,部分的介绍了uevent事件机制,这篇博文将更深入的详细分析uevent的机制以及如何android是如何透过内核传递过来的数据通过uevent机制检测设备的hotplug事件。同时也分析到了andorid_ids,还是先把get_android_id()函数拿出来分析一下吧,代码如下:
int ueventd_main(int argc, char **argv){ struct pollfd ufd; int nr; char tmp[32]; open_devnull_stdio(); log_init(); INFO("starting ueventd\n"); get_hardware_name(hardware, &revision); ueventd_parse_config_file("/ueventd.rc"); snprintf(tmp, sizeof(tmp), "/ueventd.%s.rc", hardware); ueventd_parse_config_file(tmp); ////解析ueventd.xxxxxx.rc文件,比如:goldfish为ueventd.goldfish.rc文件,具体的分析可以参考ueventd.rc device_init(); //初始化uevent socket,用于从Linux内核动态的抓取设备的状态变化,同时处理冷开机事件。 ufd.events = POLLIN; //POLLIN的意思,当内核有数据可读时,无阻塞的返回 ufd.fd = get_device_fd(); //得到相应的从内核传过来的有数据具体文件描述符fd. while(1) { //循环操作 ufd.revents = 0; nr = poll(&ufd, 1, -1); if (nr <= 0) continue; if (ufd.revents == POLLIN) handle_device_fd(); //处理具体的从内核传递过来的设备变化事件,像null、usb、ttyS0等等,很多吧。这是我的理解,如有不对之处还望见谅 } //至于内核的ueventd事件,就需要去理解linux设备驱动模型了,这个会在以后专门在linux内核栏目中详细的介绍这个,因为这个驱动模型很复杂。}
应用程序如果需要检测设备的热插拔事件,一般会用到这个特殊的socket,在linux中就是这个NETLINK,我们可以透过这个socket中的NETLINK_KOBJ_UEVEN来检测设备的热插拔的动作。其实android的文件系统采用和busybox以及udev类似的方式。在busybox中采用的mdev来自动的抓取linux所有的设备驱动,一般是从sys目录中去抓取。自动根据驱动的名称来分配相应设备的主设备号和次设备号,以及是字符设备,还是块设备和网络设备。。如果我们能够用这个方式来理解andorid的文件系统,这样对于分析android的文件系统有很大的帮助。
说了太多的废话了,还是先来具体看看device_init()函数吧,函数的具体位置在system/core/init/devices.c中,代码如下:
on early-init start ueventdon initsysclktz 0loglevel 3# setup the global environment export PATH /sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin export LD_LIBRARY_PATH /vendor/lib:/system/lib export ANDROID_BOOTLOGO 1 export ANDROID_ROOT /system export ANDROID_ASSETS /system/app export ANDROID_DATA /data export EXTERNAL_STORAGE /mnt/sdcard export ASEC_MOUNTPOINT /mnt/asec export LOOP_MOUNTPOINT /mnt/obb看到了 on early-init 下的start uventd的吗?对就是这个。因为init是个守护进程,也是内核启动之后,第一个要调用运行的程序。而init进程会首先去抓取init.rc文件。至于内核启动之后,为什么说init是第一个运行的程序呢。这个会在以后会专门开辟一篇博文来详细讲述这个问题。这里就不详细说了,好了关于ueventd部分。已经基本上分析完了,其实ueventd就是初始化内核中所有的设备驱动,然后透过ueventd分配好所有的设备。当然,这个是需要根据内核的具体已有的设备驱动。
未完,Andriod源码的分析还请继续关注《基于goldfish和android2.3.5学习之:开天辟地Android启动机制[四]》 。。。