init进程详细分析--基于android 10

2023-05-16

init进程详细分析

概述

android设备上电,引导程序引导进入boot(通常是uboot),加载initramfs、kernel镜像,启动kernel后,进入用户态程序。第一个用户空间程序是init,PID固定是1.在android系统上,init的代码位于/system/core/init下,基本功能有:

  • 管理设备
  • 解析并处理启动脚本init.rc
  • 实时维护这个init.rc中的服务

image

流程分析

这些init.rc只是语法文件,并不是程序,真正的入口则是上面提到的system/core/init/init.cpp .

  • 参考文档:
  • Android P (9.0) 之Init进程源码分析
  • Android系统init进程启动及init.rc全解析

对比老版本差异

在Android Q中,对该机制做了一些改变 。

单一的init.rc,被拆分,服务根据其二进制文件的位置(/system,/vendor,/odm)定义到对应分区的etc/init目录中,每个服务一个rc文件。与该服务相关的触发器、操作等也定义在同一rc文件中。

/system/etc/init,包含系统核心服务的定义,如SurfaceFlinger、MediaServer、Logcatd等。
/vendor/etc/init, SOC厂商针对SOC核心功能定义的一些服务。比如高通、MTK某一款SOC的相关的服务。
/odm/etc/init,OEM/ODM厂商如小米、华为、OPP其产品所使用的外设以及差异化功能相关的服务。

这样的目录结构拆分,也与Android产品的开发流程相吻合,减轻了维护的负担。下图为Android Q 中定义的所有服务。

  • k62v1_64_bsp$ find ./ -name "*.rc" :
展开查看

```
./recovery/root/init.rc
./recovery/root/ueventd.rc
./recovery/root/init.recovery.mt6762.rc
./recovery/root/init.recovery.mt6765.rc
./vendor/ueventd.rc
./vendor/etc/init/init.wmt_drv.rc
./vendor/etc/init/init.volte_imsm_93.rc
./vendor/etc/init/mtk_agpsd_p.rc
./vendor/etc/init/bootperf.rc
./vendor/etc/init/audiocmdservice_atci.rc
./vendor/etc/init/android.hardware.graphics.composer@2.1-service.rc
./vendor/etc/init/vendor.mediatek.hardware.gpu@1.0-service.rc
./vendor/etc/init/init.volte_stack.rc
./vendor/etc/init/init_connectivity.rc
./vendor/etc/init/init.fmradio_drv.rc
./vendor/etc/init/netdagent.rc
./vendor/etc/init/atcid_eng.rc
./vendor/etc/init/init.vtservice_hidl.rc
./vendor/etc/init/mtkrild.rc
./vendor/etc/init/android.hardware.health@2.0-service.rc
./vendor/etc/init/init.wfca.rc
./vendor/etc/init/modemdbfilter_service.rc
./vendor/etc/init/init.bt_drv.rc
./vendor/etc/init/init.gps_drv.rc
./vendor/etc/init/aee_aedv64.rc
./vendor/etc/init/android.hardware.secure_element@1.0-service-mediatek.rc
./vendor/etc/init/android.hardware.drm@1.2-service.clearkey.rc
./vendor/etc/init/vendor.mediatek.hardware.log@1.0-service.rc
./vendor/etc/init/init.thermal_manager.rc
./vendor/etc/init/init.bip.rc
./vendor/etc/init/init.cccimdinit.rc
./vendor/etc/init/md_monitor.rc
./vendor/etc/init/muxreport.rc
./vendor/etc/init/android.hardware.drm@1.0-service.rc
./vendor/etc/init/init.wlan_drv.rc
./vendor/etc/init/android.hardware.drm@1.2-service.widevine.rc
./vendor/etc/init/wlan_assistant.rc
./vendor/etc/init/camerahalserver.rc
./vendor/etc/init/atci_service.rc
./vendor/etc/init/android.hardware.cas@1.1-service.rc
./vendor/etc/init/ipsec_mon.rc
./vendor/etc/init/android.hardware.thermal@1.0-service.rc
./vendor/etc/init/android.hardware.gatekeeper@1.0-service.rc
./vendor/etc/init/android.hardware.keymaster@4.0-service.rc
./vendor/etc/init/init.thermalloadalgod.rc
./vendor/etc/init/android.hardware.graphics.allocator@2.0-service.rc
./vendor/etc/init/vendor.mediatek.hardware.mtkpower@1.0-init.rc
./vendor/etc/init/lbs_hidl_service.rc
./vendor/etc/init/android.hardware.sensors@2.0-service-mediatek.rc
./vendor/etc/init/hostapd.android.rc
./vendor/etc/init/init.thermal.rc
./vendor/etc/init/fuelgauged_nvram_init.rc
./vendor/etc/init/em_hidl_eng.rc
./vendor/etc/init/vendor.mediatek.hardware.mtkpower@1.0-service.rc
./vendor/etc/init/init.cccirpcd.rc
./vendor/etc/init/init.volte_md_status.rc
./vendor/etc/init/android.hardware.light@2.0-service-mediatek.rc
./vendor/etc/init/aee_aedv.rc
./vendor/etc/init/init.cccifsd.rc
./vendor/etc/init/gsm0710muxd.rc
./vendor/etc/init/loghidlvendorservice.rc
./vendor/etc/init/fuelgauged_init.rc
./vendor/etc/init/android.hardware.wifi@1.0-service-lazy-mediatek.rc
./vendor/etc/init/android.hardware.bluetooth@1.0-service-mediatek.rc
./vendor/etc/init/ppl_agent.rc
./vendor/etc/init/hw/init.project.rc
./vendor/etc/init/hw/init.sensor_1_0.rc
./vendor/etc/init/hw/init.mt6765.rc
./vendor/etc/init/hw/meta_init.connectivity.rc
./vendor/etc/init/hw/meta_init.project.rc
./vendor/etc/init/hw/multi_init.rc
./vendor/etc/init/hw/factory_init.project.rc
./vendor/etc/init/hw/factory_init.rc
./vendor/etc/init/hw/init.mt6762.rc
./vendor/etc/init/hw/init.mt6765.usb.rc
./vendor/etc/init/hw/factory_init.connectivity.rc
./vendor/etc/init/hw/init.connectivity.rc
./vendor/etc/init/hw/init.aee.rc
./vendor/etc/init/hw/init.modem.rc
./vendor/etc/init/hw/init.ago.rc
./vendor/etc/init/hw/meta_init.modem.rc
./vendor/etc/init/hw/meta_init.rc
./vendor/etc/init/init.md_apps.rc
./vendor/etc/init/android.hardware.media.omx@1.0-service.rc
./vendor/etc/init/init.volte_ua.rc
./vendor/etc/init/nvram_daemon.rc
./vendor/etc/init/init.wod.rc
./vendor/etc/init/vendor.mediatek.hardware.nvram@1.1-sevice.rc
./vendor/etc/init/android.hardware.memtrack@1.0-service.rc
./vendor/etc/init/android.hardware.configstore@1.1-service.rc
./vendor/etc/init/android.hardware.usb@1.1-service-mediatek.rc
./vendor/etc/init/vendor.mediatek.hardware.mtkcodecservice@1.1-service.rc
./vendor/etc/init/init.volte_imcb.rc
./vendor/etc/init/android.hardware.audio@5.0-service-mediatek.rc
./vendor/etc/init/android.hardware.vibrator@1.0-service.rc
./vendor/etc/init/vendor.mediatek.hardware.mms@1.3-service.rc
./vendor/etc/init/vndservicemanager.rc
./vendor/etc/init/android.hardware.gnss@2.0-service-mediatek.rc
./vendor/etc/init/vendor.mediatek.hardware.pq@2.2-service.rc
./system/apex/com.android.media.swcodec/etc/init.rc
./system/etc/init/mdlogger.rc
./system/etc/init/atrace.rc
./system/etc/init/mediaextractor.rc
./system/etc/init/surfaceflinger.rc
./system/etc/init/ashmemd.rc
./system/etc/init/android.system.suspend@1.0-service.rc
./system/etc/init/uncrypt.rc
./system/etc/init/camerapostalgo.rc
./system/etc/init/bootlogoupdater.rc
./system/etc/init/art_apex_boot_integrity.rc
./system/etc/init/usbd.rc
./system/etc/init/modemdbfilter_client.rc
./system/etc/init/atci_service_sys.rc
./system/etc/init/drmserver.rc
./system/etc/init/recovery-persist.rc
./system/etc/init/aee_aed64.rc
./system/etc/init/keystore.rc
./system/etc/init/wait_for_keymaster.rc
./system/etc/init/mobile_log_d.rc
./system/etc/init/mediaserver.rc
./system/etc/init/hwservicemanager.rc
./system/etc/init/init-debug.rc
./system/etc/init/gpuservice.rc
./system/etc/init/logd.rc
./system/etc/init/incidentd.rc
./system/etc/init/servicemanager.rc
./system/etc/init/lpdumpd.rc
./system/etc/init/idmap2d.rc
./system/etc/init/bootstat.rc
./system/etc/init/blank_screen.rc
./system/etc/init/bootstat-debug.rc
./system/etc/init/storaged.rc
./system/etc/init/netd.rc
./system/etc/init/mediametrics.rc
./system/etc/init/mediadrmserver.rc
./system/etc/init/wificond.rc
./system/etc/init/vdc.rc
./system/etc/init/cameraserver.rc
./system/etc/init/gsid.rc
./system/etc/init/consyslogger.rc
./system/etc/init/logtagd.rc
./system/etc/init/malloc_debug_option.rc
./system/etc/init/bootanim.rc
./system/etc/init/logcatd.rc
./system/etc/init/batterywarning.rc
./system/etc/init/statsd.rc
./system/etc/init/perfetto.rc
./system/etc/init/init.connectivity.rc
./system/etc/init/flags_health_check.rc
./system/etc/init/mtpd.rc
./system/etc/init/init.thermald.rc
./system/etc/init/mdnsd.rc
./system/etc/init/duraspeed.rc
./system/etc/init/emdlogger3.rc
./system/etc/init/audioserver.rc
./system/etc/init/terserver.rc
./system/etc/init/heapprofd.rc
./system/etc/init/netdiag.rc
./system/etc/init/bpfloader.rc
./system/etc/init/init.vtservice.rc
./system/etc/init/hw/init.aee.rc
./system/etc/init/hw/vendor_init_as_system.rc
./system/etc/init/emdlogger5.rc
./system/etc/init/iorapd.rc
./system/etc/init/wifi-events.rc
./system/etc/init/tombstoned.rc
./system/etc/init/kpoc_charger.rc
./system/etc/init/apexd.rc
./system/etc/init/traceur.rc
./system/etc/init/android.hidl.allocator@1.0-service.rc
./system/etc/init/gatekeeperd.rc
./system/etc/init/atrace_userdebug.rc
./system/etc/init/lmkd.rc
./system/etc/init/rss_hwm_reset.rc
./system/etc/init/installd.rc
./system/etc/init/racoon.rc
./system/etc/init/emdlogger2.rc
./system/etc/init/emdlogger1.rc
./system/etc/init/em_svr.rc
./system/etc/init/dumpstate.rc
./system/etc/init/aee_aed.rc
./system/etc/init/vold.rc
./root/init.rc
./root/init.zygote32.rc
./root/init.environ.rc
./root/ueventd.rc
./root/init.zygote64_32.rc
./root/init.preload.rc
./root/init.usb.configfs.rc
./root/init.usb.rc
```

init.rc定位

  • init的源码位于system/core/init包下,我们先从入口类main.cpp来看
int main(int argc, char** argv) {
#if __has_feature(address_sanitizer)
    __asan_set_error_report_callback(AsanReportCallback);
#endif

    if (!strcmp(basename(argv[0]), "ueventd")) {
        return ueventd_main(argc, argv);   //ueventd.cpp入口函数,初始化uevent
    }

    if (argc > 1) {
        if (!strcmp(argv[1], "subcontext")) {
            android::base::InitLogging(argv, &android::base::KernelLogger);
            const BuiltinFunctionMap function_map;

            return SubcontextMain(argc, argv, &function_map);
        }

        if (!strcmp(argv[1], "selinux_setup")) {
            // This function initializes SELinux then execs init to run in the init SELinux context.
            return SetupSelinux(argv); //对SELinux进行初始化,并通过execs的系统调用开启init进程
        }

        if (!strcmp(argv[1], "second_stage")) {
            return SecondStageMain(argc, argv);  //第二阶段 init.cpp入口函数
        }
    }

    return FirstStageMain(argc, argv);   //第一阶段
}

复制代码可以看到main.cpp的函数跟之前版本有了很大的区别,拿Android9.0的源码androidxref.com/9.0.0_r3/xr…来说,Android10中并不只是调用init::main,而是把部分流程性的判断放到的mian.cpp中来做,所以这里如果按照书上或者文章中所说的,直接去找init.cpp中的main函数,其实是找不到入口的。

当入口函数Init.cpp启动加载第一个init.rc如下:

/system/core/rootdir/init.rc
/bootable/recovery/etc/init.rc

从目录上大致可以猜测,这两个init.rc使用场景不一样,一个是刷机用到的,也就是进入recorvery模式,一个是正常启动用到的;我们这里重点分析的是正常启动用的,也是init.c关联的那个;

  • device/mediatek/mt6765/device.mk
7:  PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.vendor.rc=/vendor/etc/init/hw/

919: PRODUCT_COPY_FILES += device/mediatek/mt6765/init.recovery.mt6765.rc:recovery-vendor/init.recovery.mt6765.rc
  • /system/core/rootdir/init.rc
···
import /vendor/etc/init/hw/init.${ro.hardware}.rc
···
  • /device/mediatek/mt6765/init.mt6765.rc
···
import /vendor/etc/init/hw/init.project.rc
···
  • device/mediateksample/k62v1_64_bsp/device.mk
16:PRODUCT_COPY_FILES += $(LOCAL_PATH)/init.project.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/hw/init.project.rc

根据以上内容,我们可以判断我们OEM/ODM厂商主要修改文件是device/mediateksample/k62v1_64_bsp/init.project.rc,而在recovery模式下主要修改init.recovery.mt6765.rc文件。

init.rc修改规则

rc规则主要包含了四种类型的语句:

  1. Action
  2. Commands
  3. Services
  4. Options.

以下做具体详解:

动作(Action)

动作表示了一组命令(commands)组成.动作包括一个触发器,决定了何时运行这个动作。

注意:当触发器的条件满足时,这个动作会被增加到已被运行的队列尾。假设此动作在队列中已经存在,那么它将不会运行.

一个动作所包括的命令将被依次运行。

on  <trigger>      ## 触发条件
    <command>      ##执行命令
    <command1>     ##可以执行多个命令
  1. 触发器(trigger)

在"动作"(action)里面的,on后面跟着的字符串是触发器(trigger),trigger是一个用于匹配某种事件类型的字符串,它将对应的Action的执行。

触发器(trigger)有几种格式:

1、最简单的一种是一个单纯的字符串。比如“on boot”。这种简单的格式可以使用命令"trigger"来触发。
2、还有一种常见的格式是"on property<属性>=<值>"。如果属性值在运行时设成了指定的值,则"块"(action)中的命令列表就会执行。

常见的格式:

格式含义
on early-init在初始化早期阶段触发
on init在初始化阶段触发
on late-init在初始化晚期阶段触发
on boot/charger当系统启动/充电时触发
on property当属性值满足条件时触发

commands(命令)

command是action的命令列表中的命令,或者是service中的选项 onrestart 的参数命令.

命令将在所属事件发生时被一个个地执行.

常见命令:

命令描写叙述
exec [ ]* 运行指定路径下的程序,并传递參数.
export 设置全局环境參数。此參数被设置后对全部进程都有效.
ifup 使指定的网络接口"上线",相当激活指定的网络接口
import 导入一个额外的init配置文件.
hostname 设置主机名
chdir 改变工作文件夹.
chmod 改变指定文件的读取权限.
chown 改变指定文件的拥有都和组名的属性.
chroot 改变进行的根文件夹.
class_start <serviceclass启动指定类属的全部服务,假设服务已经启动,则不再反复启动.
class_stop 停止指定类属的所胡服务.
domainname 设置域名
insmod 安装模块到指定路径.
mkdir [mode] [owner] [group] 用指定參数创建一个文件夹,在默认情况下,创建的文件夹读取权限为755.username为root,组名为root.
mount [ ]* 类似于linux的mount指令setkey TBD(To Be Determined), 待定.
setprop 设置属性及相应的值.
setrlimit 设置资源的rlimit(资源限制),不懂就百度一下rlimit
start 假设指定的服务未启动,则启动它.
stop 假设指定的服务当前正在执行。则停止它.
symlink 创建一个符号链接.
sysclktz <mins_west_of_gmt>设置系统基准时间.
trigger Trigger an event. Used to queue an action from another action. 这名话没有理解,望高手指点.
write [ ]* 往指定的文件写字符串.

服务(services)

服务是指那些须要在系统初始化时就启动或退出时自己主动重新启动的程序.

service <name><pathname> [ <argument> ]*
    <option>
    <option>

解释一下各个参数:

参数含义
表示此服务的名称
此服务所在路径因为是可执行文件,所以一定有存储路径。
启动服务所带的参数
对此服务的约束选项

选项(option)

options是Service的修订项。它们决定一个服务何时以及如何运行.

选项描述
critical据设备相关的关键服务,如果在4分钟内,此服务重复启动了4次,那么设备将会重启进入还原模式。
disabled服务不会自动运行,必须显式地通过服务器来启动。
setenv设置环境变量
socket[ [ ] ] 在/dev/socket/下创建一个unix domain的socket,并传递创建的文件描述符fd给服务进程.其中type必须为dgram或stream,seqpacket.
user在执行此服务之前先切换用户名。当前默认为root.
group [ ]*类似于user,切换组名
oneshot当此服务退出时不会自动重启.
class给服务指定一个类属,这样方便操作多个服务同时启动或停止.默认情况下为default.
onrestart当服务重启时执行一条指令,

使用例子:

service bootanim /system/bin/bootanimation
    class core  //给服务指定一个类属,这样方便操作多个服务同时启动或停止
    user graphics //在执行此服务之前先切换用户名
    group graphics audio
    disabled  //服务不会自动运行
    oneshot  //当此服务退出时不会自动重启

启动顺序

下面为各个section的执行顺序,英文编号的section是系统内建的(写死在init.cpp中的命令)

1) early-init

    a) wait_for_coldboot_done

    b) property_init

    c) keychord_int

    d) console_init

2) init

3) early-fs (sys.boot_from_charger_mode=1)

4) fs
5) post-fs

6) late-fs

7) post-fs-data

8) load_persist_props_action

9) zygote-start

10) firmware_mounts_complete

11) early-boot

12) boot

13) service

所有的action运行于service之前。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

init进程详细分析--基于android 10 的相关文章

随机推荐

  • 设置eMMC和DDR的工作频率

    1 MTK 平台查看eMMC和DDR的工作频率 eMMC xff1a adb shell span class token function cat span sys kernel debug mmc0 clock DDR xff1a ad
  • 命令设置Android手机不进入休眠

    在Linux系统中 xff0c wake lock是一直锁机制 xff0c 只要有驱动占用这个锁 xff0c 系统就不会进入深度休眠 获取此锁的方式如下 xff1a adb shell span class token keyword ec
  • Kconfig文件的用途及解析

    1 Kconfig文件的作用 首先 xff0c 内核编译代码的大概过程如下 xff1a 遍历每个源码目录Makefile 61 gt 根据每个目录的Kconfig来配置Makefile xff0c 定制要编译的对象 61 gt 回到顶层目录
  • git format-patch用法

    1 命令介绍 git format patch用来对某次提交生成patch xff0c 方便发送给其他人员进行参考或者同步 2 生成patch用法 基于上几次内容打包 有几个 就会打几个patch xff0c 从最近一次打起 git for
  • SELinux权限添加

    1 avc denied log 如下 span class token number 01 span span class token operator span span class token number 01 span span
  • Android常见指令汇总

    1 查看UID对应的APK 一个UID对应一个APK adb pull data system packages list 2 adb开关机指令 adb span class token function reboot span span
  • WiFi Direct(WiFi P2P)

    Wi Fi Direct技术是Wi Fi产业链向蓝牙技术发起的挑战 xff0c 它试图完全取代蓝牙 Wi Fi Direct是一种点对点连接技术 xff0c 它可以在两台station之间直接建立tcp ip链接 xff0c 并不需要AP的
  • C++经典面试题(九)

    最近看一些面试题 xff0c 觉得如果自己被问到了 xff0c 并不能很利落的回答出来 一是从来没有这个意识 xff0c 二是没有认真的梳理下 下面对这些题做出分析 xff0c 哈 xff01 个人能力有限 xff0c 其中难免有疏漏 xf
  • 我的大学——学习生活总结

    纪念我终将逝去的青春 大一上學期 專業 1 C語言K amp R amp amp 習題 2 C語言經典習題 3 C語言趣味習題 4 C陷阱与缺陷 5 彙編語言 6 C 43 43 程序設計 7 C 程序設計
  • 基于Python的开源人脸识别库:离线识别率高达99.38%——新开源的用了一下感受一下

    该项目是要构建一款免费 开源 实时 离线的网络 app xff0c 支持组织者使用人脸识别技术或二维码识别所有受邀人员 有了世界上最简单的人脸识别库 xff0c 使用 Python 或命令行 xff0c 即可识别和控制人脸 该库使用 dli
  • 5G智慧医疗十大应用场景,你知道多少?

    来源 xff1a 北京物联网智能技术应用协会 都说5G会改变千行百业 xff0c 其中 xff0c 5G医疗健康就是5G技术在医疗健康行业的一个重要应用领域 随着 5G 正式商用的到来以及与大数据 互联网 43 人工智能 区块链等前沿技术的
  • 全网最详细的排列组合系列算法题整理

    写在前面 LeetCode上面排列组合系列几乎所有题目放在一起整理了一下 面试题 08 07 无重复字符串的排列组合 无重复字符串的排列组合 编写一种方法 xff0c 计算某字符串的所有排列组合 xff0c 字符串每个字符均不相同 示例 输
  • 使用IDEA从git拉取分支

    一 打开IDEA xff0c 进入目录 xff1a File gt New gt Project from Version Control 二 打开git工程 xff0c 进行clone对应的链接 填充对应的链接 三 默认下载的是maste
  • 用了cloudflare后,网站提示Sorry, you have been blocked怎么解决?

    其实cloudflare还是非常智能的 xff0c 但有时候为了安全起见 xff0c 我们在网站后台修改参数的时候会被CF拦截 xff0c 我就遇到了好几次提示Sorry you have been blocked的情况 遇到这种情况后 x
  • 下载网页视频的方法

    随着技术的不断更新 xff0c 现在小视频越来越火 xff0c 有的时候想保存浏览的小视频 xff0c 可不知道如何下载 xff1f 对于一些非专业的视频网站的小视频应该通过浏览器的选项是可以下载和保存的 下面就介绍使用浏览器下载的方法 1
  • tomcat8.0.9的安装

    免安装版的tomcat http download csdn net detail u011731233 7632475 这个解压之后 xff0c 在myeclipse中指定到tomcat目录就可以用了 xff0c 也不用配置环境变量 下载
  • 【多线程/C++】阻塞队列的C++多线程 实现 BlockingQueue

    阻塞队列在存放和获取队列中的数据时需要使用多线程 xff0c 一个线程专门负责向队列中存放元素 xff0c 另一个线程专门从队列中获取元素 也可多开辟跟多的线程进行存取 规范的方法也正是存放和获取队列元素分别在不同的线程中实现 阻塞队列实现
  • Log4J使用详解(整理)

    1 Log4j是什么 Log4j是Apache的一个开源项目 xff0c 通过使用Log4j xff0c 我们可以控制日志信息输送的目的地是控制台 文件 GUI组件 xff0c 甚至是套接口服务器 NT的事件记录器 UNIX Syslog守
  • DelphiXE10.2.3实现线程安全访问数据和对象(四)——实现原子自旋锁的无锁对象池

    无锁对象池与无锁Hash是不同应用场景中使用 xff0c 无锁Hash只是预先创建好Hash表 xff08 当然也可以动态Add xff09 后 xff0c 供调用者通过Key值快速找到保存的数据 xff0c 并读取 xff08 这里就只能
  • init进程详细分析--基于android 10

    init进程详细分析 概述 android设备上电 xff0c 引导程序引导进入boot 通常是uboot xff0c 加载initramfs kernel镜像 xff0c 启动kernel后 xff0c 进入用户态程序 第一个用户空间程序