1. 概述
1.1 概述
之前分析過android5的init.rc,不過還是不夠仔細,現在來看看android6的,多的就不寫了,只寫關鍵點
忘記一些基本概念可以先看看之前的筆記:
Android5.1.1 初始化流程之init進程(未完成)
i.mx6 Android5.1.1 初始化流程之init.rc解析(未完成)
涉及到的文件為:
/system/core/init/init.cpp (init進程)
/system/core/rootdir/init.rc (Google原生init.rc)
1.2 查找所有init.rc
init.rc只會存在於/system(android原生rc)和/device(硬件廠商特定的rc:一般為特定硬件或開發板特定的的東西,而非原生android中通用的)當中
1). 搜索/system:
hejin@desk-ubuntu:/home/desk/aplex_m6.1.1_2.1.0/device$ cd ../system/ hejin@desk-ubuntu:/home/desk/aplex_m6.1.1_2.1.0/system$ find -name "init*.rc" ./core/rootdir/init.zygote64.rc ./core/rootdir/init.rc ./core/rootdir/init.zygote32.rc ./core/rootdir/init.usb.rc ./core/rootdir/init.usb.configfs.rc ./core/rootdir/init.zygote64_32.rc ./core/rootdir/init.trace.rc ./core/rootdir/init.zygote32_64.rc
2). 搜索/device:(然后根據目錄的路徑名查找出跟我們相關的)
hejin@desk-ubuntu:/home/desk/aplex_m6.1.1_2.1.0$ find device/ -name "init*.rc" ...
device/fsl/sabresd_6dq/init.i.MX6Q.rc device/fsl/sabresd_6dq/init.rc device/fsl/imx6/init.recovery.freescale.rc device/fsl/imx6/etc/init.usb.rc
3). 在編譯完成之后,所有用到的init.rc都會放在/home/desk/aplex_m6.1.1_2.1.0/out/target/product/sabresd_6dq/root/目錄下面,也可以直接查看:
hejin@desk-ubuntu:/home/desk/aplex_m6.1.1_2.1.0$ ls out/target/product/sabresd_6dq/root/*.rc out/target/product/sabresd_6dq/root/init.environ.rc out/target/product/sabresd_6dq/root/init.freescale.i.MX6DL.rc out/target/product/sabresd_6dq/root/init.freescale.i.MX6QP.rc out/target/product/sabresd_6dq/root/init.freescale.i.MX6Q.rc out/target/product/sabresd_6dq/root/init.freescale.rc out/target/product/sabresd_6dq/root/init.freescale.usb.rc out/target/product/sabresd_6dq/root/init.rc out/target/product/sabresd_6dq/root/init.recovery.freescale.rc out/target/product/sabresd_6dq/root/init.trace.rc out/target/product/sabresd_6dq/root/init.usb.configfs.rc out/target/product/sabresd_6dq/root/init.usb.rc out/target/product/sabresd_6dq/root/init.zygote32.rc out/target/product/sabresd_6dq/root/ueventd.freescale.rc out/target/product/sabresd_6dq/root/ueventd.rc
2. 總體流程
/system/core/rootdir/init.rc這個目錄為init.rc,這個就是android6.0.1真正Google原生的init.rc,然后這個原生init.rc會通過import導入一些其他的init.rc,其中就包括我們設備的
在這個目錄里面又會導入幾個init.rc
import /init.environ.rc import /init.usb.rc import /init.${ro.hardware}.rc //通過getprop可以查看到ro.hardware為:freescale;看名字就知道為芯片原廠定義的init.rc,我們需要修改,一般就在這里面 import /init.usb.configfs.rc import /init.${ro.zygote}.rc import /init.trace.rc
查看源碼:/system/core/init/init.cpp
int main(int argc, char** argv) { if (!strcmp(basename(argv[0]), "ueventd")) { return ueventd_main(argc, argv); } ... init_parse_config_file("/init.rc"); action_for_each_trigger("early-init", action_add_queue_tail); ... action_for_each_trigger("init", action_add_queue_tail); queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); char bootmode[PROP_VALUE_MAX]; if (property_get("ro.bootmode", bootmode) > 0 && strcmp(bootmode, "charger") == 0) { action_for_each_trigger("charger", action_add_queue_tail); } else { action_for_each_trigger("late-init", action_add_queue_tail); } queue_builtin_action(queue_property_triggers_action, "queue_property_triggers"); while (true) { ... } return 0; }
注意到紅色那幾個,流程為:early-init --> init --> late-init
1). early-init:
主要是啟動了ueventd,這個進程會做設備節點。然后在init進程加載這個trigger之后,會去等一個/dev/.coldboot_done文件,這個文件當ueventd設備節點都做好了會去寫這個文件。
2). init:
這里面主要是創建一些目錄,chown chmod操作
3). late-init: (作用:掛在文件系統和系統系統核心服務)
我們看下面late-init中又分了多個trigger,並且每一個做什么都寫好了。
on late-init trigger early-fs //掛fstab.freescale里面的 trigger fs //掛fstab.freescale里面的 trigger post-fs //創建一堆的目錄和數據 # Load properties from /system/ + /factory after fs mount. Place # this in another action so that the load will be scheduled after the prior # issued fs triggers have completed. trigger load_system_props_action //加載系統屬性 # Now we can mount /data. File encryption requires keymaster to decrypt # /data, which in turn can only be loaded when system properties are present trigger post-fs-data //創建data下面的目錄 trigger load_persist_props_action //加載永久屬性 # Remove a file to wake up anything waiting for firmware. trigger firmware_mounts_complete trigger early-boot trigger boot //啟動boot
boot中啟動core服務,core服務有ueventd、logd、healthd、sh、adbd、servicemanager、vold、SurfaceFlinger、bootanimation。
on boot ... chown root system /sys/module/lowmemorykiller/parameters/adj chmod 0664 /sys/module/lowmemorykiller/parameters/adj chown root system /sys/module/lowmemorykiller/parameters/minfree chmod 0664 /sys/module/lowmemorykiller/parameters/minfree
...
class_start core //啟動所有class標記為core的服務
2. 服務類型
2.1 init.rc中服務的描述
接在上面的,在啟動了core類型的所有服務,那么現在具體講講服務有哪幾個類型,每個具體干了什么
基本的服務類型包括三種:core(最重要的)、main(次級重要的)、late_start(不那么重要的)
這三類服務分別通過class_start, class_reset, class_stop來對統一類的服務進行統一的操作。
相同類別的服務,基本上是同時啟動,相互之間的延時很小。
2.2. core類服務
對/system/core/rootdir/init.rc中的class core進行全局搜索(未全部寫入,很多不重要的,也有我看不懂重不重要的):
| ueventd | /sbin/ueventd |
| logd | /system/bin/logd |
| healthd | /sbin/healthd |
| console | /system/bin/sh |
| adbd | /sbin/adbd |
| servicemanager | /system/bin/servicemanager |
| vold | /system/bin/vold |
| surfaceflinger | /system/bin/surfaceflinger |
| bootanim | /system/bin/bootanimation |
可以看到,core服務都是系統最基本的服務,只要core服務全部啟動,手機此時是可以運行的,但是卻看不到東西,原因是framework沒有啟動。此時啟動的都是C,C++的進程。
2.3. main類服務
對/system/core/rootdir/init.rc中的class main進行全局搜索(未全部寫入,很多不重要的,也有我看不懂重不重要的):
| netd | /system/bin/netd |
| debuggerd | /system/bin/debuggerd |
| debuggerd64 | /system/bin/debuggerd64 |
| ril-daemon | /system/bin/rild |
| surfaceflinger | /system/bin/surfaceflinger |
| media | /system/bin/mediaserver |
| bootanim | /system/bin/bootanimation |
| installd | /system/bin/installd |
| sshd | /system/bin/start-ssh |
| zygote | /system/bin/app_process |
可以看到main的服務相對多一些,看到zygote了吧,由此可見main服務大部分是建立在java層或者與java層息息相關的系統服務。
2.4. late_start類服務
字面意思是晚些啟動。/device/中一些硬件廠商的.rc文件中會將一些服務設置為該類。
3. device目錄下的啟動
流程:
1. 首先通用mk: device/fsl/imx6/imx6.mk
2. 執行具體架構和模式的mk: device/fsl/imx6/sabresd_6dq.mk (在這里面會將第3步中的需要執行的服務文件全部復制out/target中的系統中去,注意:有一些文件復制過程中會改變名字,例如init.rc就改為了init.freescale.rc)
PRODUCT_COPY_FILES += \ device/fsl/sabresd_6dq/init.rc:root/init.freescale.rc \ //將init.rc復制到out/target/product/sabresd_6dq/root/init.fresscale.rc device/fsl/sabresd_6dq/init.i.MX6Q.rc:root/init.freescale.i.MX6Q.rc \
3. 執行服務: init.rc等等 (注意:這一步並不是在編譯時候運行,而是在第2步拷貝給android系統,在android啟動后執行的文件)
參考資料:
http://blog.csdn.net/u010753159/article/details/51981121
http://blog.csdn.net/longyc2010/article/details/39616979
