Android是一种基于Linux的开发源代码软件栈,为各类设备和机型而创建。可以参考谷歌官方的介绍。下图为参考官方原图而绘制的Android软件堆栈图
Android系统启动
Android 系统启动流程是什么?
-
Powon上电后,CPU读取ROM中固定的地址,开始加载Bootloader到RAM中,然后执行Bootloader。
-
Bootloader:芯片生产后就烧录好的,主要是初始化外设(网络、内存等)、引导Kernel启动,设置启动参数。
-
Kernel:
- 初始化硬件设置、挂载根文件系统
- 加载驱动程序
- 寻找init文件,启动init进程
-
Android系统初始化过程:
- 挂载分区、创建目录,比如/dev, /proc等
- 动态加载驱动
- 启动系统服务:servicemanager、adbd、surfaceflinger、zygote......
- 配置环境变量
- 守护系统
优化Android系统的启动时间,从Uboot、Kernel、和Android系统初始化这三个过程进行优化。根据log分析出比较耗时的过程。
Android启动模式
- recovery升级模式:启动recovery分区内核和文件系统。
- 正常启动模式:引导内核和启动Android系统。
Init守护进程
Init进程是Linux内核启动完成后在用户空间启动的第一个进程(pid=1),主要负责初始化工作,启动属性服务,解析init.rc并启动Zygoter进程(Java进程的祖先),同时也会创建Binder服务大管家(servicemanager进程)。
init进程的作用:
- 解析并运行所有的init.rc文件
- 会创建目录、挂载分区,生成设备驱动节点。
- 初始化和启动属性服务
init进程main
- init进程源码文件位置system/core/init/init.cpp
- init系统中位置 /init
内核启动后,会调用system/core/init/目录下的main.cpp中的main()函数,main函数中可以看出有5个重要的阶段,且都是单独执行的,分别是
- ueventd_main:init 进程创建子进程uevented,负责设备节点的创建、权限设定等一系列工作
- SubcontextMain : 初始化日志系统
- SetupSelinux : 启动Selinux安全策略
- SecondStageMain : 位于init.cpp中,用来启动init.rc脚本
- FirstStageMain : 负责设置加载系统其余部分的最低要求。具体来说就是挂载/dev,/proc 以及将system.img挂载移动到有ramdisk的设备的/下。
// system/core/init/main.cpp
using namespace android::init;
int main(int argc, char** argv) {
#if __has_feature(address_sanitizer)
__asan_set_error_report_callback(AsanReportCallback);
#elif __has_feature(hwaddress_sanitizer)
__hwasan_set_error_report_callback(AsanReportCallback);
#endif
// Boost prio which will be restored later
setpriority(PRIO_PROCESS, 0, -20);
if (!strcmp(basename(argv[0]), "ueventd")) {
//init 进程创建子进程uevented,负责设备节点的创建、权限设定等一系列工作
return ueventd_main(argc, argv);
}
if (argc > 1) { //如果有参数,则根据不同的参数执行不同的逻辑,实现不同的功能。
if (!strcmp(argv[1], "subcontext")) {
android::base::InitLogging(argv, &android::base::KernelLogger);
const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();
// 初始化日志系统
return SubcontextMain(argc, argv, &function_map);
}
if (!strcmp(argv[1], "selinux_setup")) {
//启动Selinux安全策略
return SetupSelinux(argv);
}
if (!strcmp(argv[1], "second_stage")) {
// 执行第二阶段启动
return SecondStageMain(argc, argv);
}
}
// 执行第一阶段启动
return FirstStageMain(argc, argv);
}
SecondStageMain
SecondStageMain()方法在init.cpp
//system/core/init/init.cpp
int SecondStageMain(int argc, char** argv) {
//在设置了REBOOT_BOOTLOADER_ON_PANIC参数后,将会捕获所有init和内核崩溃的信号,方便开发时进行处理。非开发版本一般关闭。
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
}
boot_clock::time_point start_time = boot_clock::now(); //记录启动的时间
trigger_shutdown = [](const std::string& command) { shutdown_state.TriggerShutdown(command); };
SetStdioToDevNull(argv); //将stin/stdou/stderr全部重定向到/dev/null/
InitKernelLogging(argv); //初始化内核日志,失败时转储堆栈信息
LOG(INFO) << "init second stage started!";
....
ActionManager& am = ActionManager::GetInstance();
ServiceList& sm = ServiceList::GetInstance();
LoadBootScripts (am, sm); //加载init.rc脚本
...
return 0;
}
LoadBootScripts
从ro.boot.init_rc属性中找到init.rc脚本并加载,如果没有则加载下边相关的init.rc文件。最后通过ActionManager和ServiceList执行启动相关服务。
// system/core/init/init.cpp
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
Parser parser = CreateParser(action_manager, service_list);
std::string bootscript = GetProperty ( "ro.boot.init_rc" , "" );
if (bootscript.empty()) {
parser.ParseConfig("/system/etc/init/hw/init.rc");
if (!parser.ParseConfig("/system/etc/init")) {
late_import_paths.emplace_back("/system/etc/init");
}
// late_import is available only in Q and earlier release. As we don't
// have system_ext in those versions, skip late_import for system_ext.
parser.ParseConfig("/system_ext/etc/init");
if (!parser.ParseConfig("/vendor/etc/init")) {
late_import_paths.emplace_back("/vendor/etc/init");
}
if (!parser.ParseConfig("/odm/etc/init")) {
late_import_paths.emplace_back("/odm/etc/init");
}
if (!parser.ParseConfig("/product/etc/init")) {
late_import_paths.emplace_back("/product/etc/init");
}
} else {
parser.ParseConfig(bootscript);
}
}
Zygote进程
Zygote进程是一个进程孵化器,负责创建虚拟机实例、应用程序进程、系统服务进程SystemServer。他通过fork的方式创建子进程,子进程能继承父进程的系统资源,例如常用类、注册的JNI函数、共享库等。
暂时无法在飞书文档外展示此内容
Init.rc脚本
Android8.0对init.rc文件进行了拆分,比如64位的Zygote的启动脚本在init.zygote64.rc文件中。
Init.rc有Android Init Language (AIL)编写,由5大类语句组成:操作Actions、命令Commands、服务Services、选项Options和导入Imports。
init.rc里通过${ro.zygote}属性的值来决定引入Zygote相关的配置,这里有四种取值,在/system/core/rootdir/目录下可以看到4个Zygote相关的配置文件,表示系统所支持的程序的bit位数:
- init.zygote32.rc : Zygote进程的执行程序路径为/system/bin/app_process
- init.zygote64.rc : Zygote进程的执行程序路径为/system/bin/app_process64
- init.zygote64_32.rc:会启动两个Zygote,64位为主模式。
#/system/core/rootdir/init.rc import /init.environ.rc
import /system/etc/init/hw/init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /system/etc/init/hw/init.usb.configfs.rc
import / system /etc/init/hw/init.${ro.zygote}.rc
# Cgroups are mounted right before early-init using list from /etc/cgroups.json
on early-init
# Disable sysrq from keyboard
write /proc/sys/kernel/sysrq 0
# Android doesn't need kernel module autoloading, and it causes SELinux
# denials. So disable it by setting modprobe to the empty string. Note: to
# explicitly set a sysctl to an empty string, a trailing newline is needed.
write /proc/sys/kernel/modprobe \n
# Set the security context of /adb_keys if present.
restorecon /adb_keys
......
init.zygote64.rc
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
- service表示Zygote进程以服务的形式来启动,
- Zygote 进程的名字
- /system/bin/app_process64是执行程序的路径
- --start-system-server表示zygote启动后需要启动SystemServer进程。
socket zygote stream 660 root system
- zygote进程通过socket来进行跨进程通信,会创建一个名为zygote的socket,660表示权限是rw-rw---。
#/system/core/rootdir/init.zygote64.rc service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main //伴随着 main class启动而启动
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system //创建socket, 名字是zygote
socket usap_pool_primary stream 660 root system
onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media //当zygote重启时,则会重启media
onrestart restart media.tuner
onrestart restart netd //当zygote重启时,则会重启netd
onrestart restart wificond
task_profiles ProcessCapacityHigh
critical window=${zygote.critical_window.minute:-off} target=zygote-fatal
app_process64
init启动后通过fork和execve来启动Zygoter进程
然后执行app_process64中的main函数用来启动Java虚拟机
#frameworks/base/cmds/app_process/app_main.cpp int main(int argc, char* const argv[])
{
if (!LOG_NDEBUG) {
String8 argv_String;
for (int i = 0; i < argc; ++i) {
argv_String.append(""");
argv_String.append(argv[i]);
argv_String.append("" ");
}
ALOGV("app_process main with argv: %s", argv_String.string());
}
AppRuntime runtime (argv[ 0 ], computeArgBlockSize(argc, argv)) ; //创建AppRuntime对象
// Process command line arguments
// ignore argv[0]
argc--;
argv++;
}
}
.........................
if (zygote) { //使用runtime.start启动Zygote进程
runtime. start ( "com.android.internal.os.ZygoteInit" , args, zygote); } else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
}
AndroidRuntime#start
- 启动Java virtual machine
- 为JVM注册JNI方法
- 根据传入的com.android.internal.os.ZygoteInit,通过JNI调用其main方法
#frameworks/ base/core/jni/AndroidRuntime.cpp:1193
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
ALOGD(">>>>>> START %s uid %d <<<<<<\n",
className != NULL ? className : "(unknown)", getuid());
.............
/* 启动JAVA虚拟机 * / JniInvocation jni_invocation; jni_invocation. Init ( NULL ); JNIEnv env;
if ( startVm (&mJavaVM , &env, zygote, primary_zygote) != 0 ) {
return ;
}
onVmCreated(env);
/*
* Register android functions.
* /
//JNI方法注册 if ( startReg (env) < 0 ) { ALOGE ( "Unable to register all android natives\n" ); return ; } ............ char slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going * / } else { jmethodID startMeth = env-> GetStaticMethodID (startClass, "main" , "([Ljava/lang/String;)V" ); if (startMeth == NULL ) { ALOGE ( "JavaVM unable to find main() in '%s'\n" , className); / keep going */
} else {
//startClass = com.android.internal.os.ZygoteInit
//startMeth = main env-> CallStaticVoidMethod (startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
.........
}
ZygoteInit#main
com.android.internal.os.ZygoteInit#main
public static void main(String[] argv) {
.............................
boolean startSystemServer = false; //是否创建SystemServer
String zygoteSocketName = "zygote"; //默认的socket名字
String abiList = null;
boolean enableLazyPreload = false; //是否延迟加载资源
//在init.zygote64.rc 是否有start-system-server for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
//init.rc可以通过--socket-name=指定socket名字来覆盖默认值 zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
...........
Zygote.initNativeState(isPrimaryZygote);
ZygoteHooks.stopZygoteNoThreadCreation();
//创建一个ZygoteServer
zygoteServer = new ZygoteServer (isPrimaryZygote);
//启动SystemServer,fork一个SystemServer进程,并开始运行。
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
/ /等待AMS请求,AMS会通过socket请求Zygote创建应用程序。
// The select loop returns early in the child process after a fork and
// loops forever in the zygote.
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with fatal exception", ex);
throw ex;
} finally {
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}
}
SytemServer进程
- 创建looper:Looper.prepareMainLooper();
- 初始化native service:加载动态库libandroid_servers.so
- 创建上下文:createSystemContext();
- 创建SystemServerManager,用于服务的创建,启动和生命周期管理。
- 启动引导服务:startBootstrapServices,例如AMS、PMS,ATMS
- 启动核心服务:startCoreServices
- 启动其他服务:startOtherServices,例如WMS
- 开启loop循环:Looper.loop();
startBootstrapServices
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
......
// Activity manager runs the show.
t.traceBegin("StartActivityManager");
// TODO: Might need to move after migration to WM.
ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
mSystemServiceManager, atm);
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
mWindowManagerGlobalLock = atm.getGlobalLock();
t.traceEnd();
.......
t.traceBegin("StartPowerManager");
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
t.traceEnd();
......
// Display manager is needed to provide display metrics before package manager
// starts up.
t.traceBegin("StartDisplayManager");
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
t.traceEnd();
......
t.traceBegin("StartPackageManagerService");
try {
Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
mPackageManagerService = PackageManagerService.main(
mSystemContext, installer, domainVerificationService,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF);
} finally {
Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
}
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
t.traceEnd();
}
startCoreServices
startOtherServices
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
t.traceBegin("startOtherServices");
t.traceBegin("StartWindowManagerService");
// WMS needs sensor service ready
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_SENSOR_SERVICE);
wm = WindowManagerService.main(context, inputManager, !mFirstBoot,
new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_HIGH
| DUMP_FLAG_PROTO);
t.traceEnd();
t.traceBegin("SetWindowManagerService");
mActivityManagerService.setWindowManager(wm);
t.traceEnd();
t.traceBegin("WindowManagerServiceOnInitReady");
wm.onInitReady();
t.traceEnd();
t.traceBegin("StartSystemUI");
try {
startSystemUi(context, windowManagerF);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
t.traceEnd();
}