imx6 Android6.0.1 init.rc解析


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

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM