Android 系统启动过程分析
power on
bootloader
uboot
初始化外设,引导内核启动
设置启动参数
kernel
硬件设置
驱动加载
根据uboot配置参数启动系统
Android
挂载分区,创建目录
动态加载驱动
启动系统服务: mediaserver, servicemanager, adbd, bootanimation, surfaceflinger, zygote ...
配置环境变量:硬件设置软件设置等;
守护系统;
Android 启动分析
启动脚本
init 守护进程
启动脚本语法
启动脚本解析
启动脚本中服务
Zygote 启动分析
zygote启动流程分析
java虚拟机启动和配置
zygote启动分析
zygote作用
systemserver服务介绍
Android启动模式
recovery升级模式: 启动recovery分区内核和文件系统;
正常启动模式: 引导正常内核和启动Android系统;
Android 启动过程
uboot
if (recovery命令)
{
recovery
}
等待按键消息
if (pressed recovery)
{
recovery
}
boot
recovery有一套自己的简单文件系统;挂载system分区,根据差分包跟新system,或者使用完成升级包直接覆盖;
正常升级完成后擦除recovery命令,并重启系统进入正常模式:
Android init进程
源码位置 system/core/init/init.cpp 主要参考main()函数
编译之后会放在系统的 /init
init进程的主要任务
linux第一个应用程序
创建目录,挂载分区,创建目录
解析启动脚本
启动服务
守护服务
init 进程源码分析 system/core/init/init.cpp
创建目录
klog_init() 将log重定向到 /proc/kmsg //InitKernelLogging()->android::base::InitLogging(argv, &android::base::KernelLogger, InitAborter);->KernelLogger()->klog_fd "/dev/kmsg";
property_init() 初始化环境变量 // 访问/system/etc/selinux/plat_property_contexts等
get_hardware_name() 打开/proc/cpuinfo 获取硬件信息 //
process_kernel_cmdline() 解析内核启动参数 // android::base::ReadFileToString("/proc/cmdline", &cmdline);
property_load_boot_defaults() 导入默认环境变量
get_kernel_cmdline_partitions() 得到系统分区 //
LoadBootScripts(); 加载初始化脚本 /init.rc 等;
Android 启动脚本
init.rc
path: system/core/rootdir/init.rc
import
on xxx
services
cmd
主要有以下几种
import 导入其他脚本
on 设置某个操作的启动阶段
on trigger 使用条件变量来决定是否需要执行
service 启动服务
首先有以下引用
import /init.environ.rc # system/core/rootdir/init.environ.rc.in
import /init.usb.rc # system/core/rootdir/init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /init.usb.configfs.rc
import /init.${ro.zygote}.rc
on early-init
on init
on property:sys.boot_from_charger_mode=1
on load_persist_props_action
on firmware_mounts_complete
on late-init
on post-fs
on late-fs
on post-fs-data
on zygote-start && property:ro.crypto.state=unencrypted
on zygote-start && property:ro.crypto.state=unsupported
on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file
on boot
on nonencrypted
on property:sys.init_log_level=*
on charger
on property:vold.decrypt=trigger_reset_main
on property:vold.decrypt=trigger_load_persist_props
on property:vold.decrypt=trigger_post_fs_data
on property:vold.decrypt=trigger_restart_min_framework
on property:vold.decrypt=trigger_restart_framework
on property:vold.decrypt=trigger_shutdown_framework
on property:sys.boot_completed=1
on property:sys.sysctl.extra_free_kbytes=*
on property:sys.sysctl.tcp_def_init_rwnd=*
on property:security.perf_harden=0
on property:security.perf_harden=1
on property:ro.debuggable=1
on property:aptiv.ota_cache.mount=1
on property:aptiv.ota_cache.mount=0
然后是
service ueventd /sbin/ueventd
service console /system/bin/sh
service flash_recovery /system/bin/install-recovery.sh
on 选项大致分为
on early-init
on early-boot
on boot
on init
on trigger (条件 + cmd)
service 启动服务,可以被系统守护
service name path arg # name:服务名称, path:执行文件路径, arg:执行文件参数
user xxx
group xxx
oneshot/disable # 只启动一次/关闭的
Android 启动脚本的解析
init进程分析:
init启动脚本
init_parse_config_file 解析启动脚本
action_for_each_trigger 将解析脚本中对应的操作加到 action_queue 队列中
queue_builtin_action 将解析脚本中对应的操作加到 action_queue 队列中
创建并守护进程
最新代码中的实现方式改为C++实现
LoadBootScripts() -> CreateParser().ParseConfig() -> ParseConfigFile();
参考: https://blog.csdn.net/leejunyeah/article/details/87981301
虚拟机创建和第一个java程序引导
启动脚本中定义
system/core/rootdir/init.zygote32.rc:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
system/core/rootdir/init.zygote64.rc:
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
/system/bin/app_process -Xzygote
/system/bin --zygote --start-system-server
app_process
AndroidRuntime.start()
app_process 程序入口
frameworks\base\cmds\app_process\app_main.cpp
其中部分 AndroidRuntime 方法实现在这里
frameworks\base\core\jni\AndroidRuntime.cpp
runtime.start("com.android.internal.os.ZygoteInit", startSystemServer)
{
-> startVm() -> JNI_CreateJavaVM() -> dvmCreateJNIEnv()
-> startReg() -> register_jni_procs();
-> start zygote service()
{
startClass = env->FindClass(slashClassName);
startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V");
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
}