Android系统启动流程

时间:2021-07-31 16:46:15

Android系统启动流程

 

一、Bootloader引导

路径:bootable/bootloader/*

加电后,CPU先执行bootloader引导程序,正常启动系统,加载boot.imgRAM,然后执行,boot.img中包含内核。

引导程序是在Android操作系统开始运行前的一个小程序。引导程序是运行的第一个程序,因此它是针对特定的主板与芯片的,不是Android操作系统的一部分。引导程序是OEM厂商或者运营商加锁和限制的地方。

引导程序分两个阶段执行。第一个阶段,检测外部的RAM及加载对第二阶段有用的程序;第二阶段,引导程序设置网络、内存等。这些对于运行内核是必要的,为了达到特殊的目标,引导程序可以根据配置参数或者输入数据设置内核。

 

二、Linux Kernel启动

路径:kernel/*

bootloader加载kernelkernel经自解压、初始化、载入built-in驱动程序,完成启动。Kernel启动后会创建若干内核线程(kernel thread),之后装入并执行程序/sbin/init/,载入init process,切换至user-space

 

三、Android启动

AndroidLinux系统启动有4个步骤:

1) init进程启动

2) Native服务启动

3) System ServerAndroid服务启动

4) Home启动

总体启动框架如下图:

 Android系统启动流程

 

3.1 init进程启动

路径:system/core/init

Init进程是一个由内核启动的用户级进程。内核自行启动(已经被载入内存,开始运行,并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程。init始终是第一个进程,我们可以称它为root进程或者所有进程的父进程。

Init进程一起来就根据init.rcinit.xxx.rc(硬件平台相关)脚本文件建立个几个基本服务:

ServiceManager

Zygote

Vold

......

最后init并不退出,而是担当property service的功能。

服务启动机制:

1) system/core/init/init.cpp文件main函数中parse_config_file(init.rc)读取并解析init.rc文件内容。将service信息放置到system/core/init/init_parser.cppservice_list

2) system/core/init/init.cpp文件main函数继续执行restart_servie_if_needed(...) -> service_start(...) -> Execve(...)建立service进程

 

Init.rcAndroid自己规定的初始化脚本(Android Init Language, system/core/init/readme.txt),该脚本包含四个类型声明:

Actions

Commands

Services

Options(对服务的描述,影响init进程如何以及何时启动服务)

 

具体在system/core/init/init.cpp中,会一步步完成以下工作:

1) 启动准备:该阶段包括创建文件系统的基本目录、打开基本输入、输出设备,初始化日志功能等;

mkdir -> mount -> open_devnull_stdio -> klog_init

2) 解析init.rc文件:该阶段对init.rc脚本文件进行解析,主要对serviceaction进行解析并放入到对应的service/action_list列表中,其中Service由命令(command)和一系列服务的附加内容(option)选项组成,如:”service vold /system/bin/vold”为一个service,而”socket vold stream 0660 root mount”则为配合该服务使用的optionAction则由一系列的命令组成,如:”on init mkdir /system”为系统初始化时建立系统文件夹的action

init_parse_config_file -> parse_config -> parse_new_section -> parse_service/parse_action -> parse_line_service/parse_line_action

3) 触发需要执行的actionAction需要在Triggers(触发条件)中调用,本阶段对需要执行的Action进行触发,并根据触发条件将需要执行的Action放入Action队列;

action_for_each_trigger(early-init,init,charger,ffbm,late-init) -> action_add_queue_tail -> action_remove_queue_head -> do_class_start

4) 执行在action队列中的命令:对上一阶段触发的ActionService进行执行,并在此过程中,派生了ZygoteServiceManager两个非常重要的进程;

execute_one_command -> action_remove_queue_head -> do_class_start -> service_for_each_class -> service_start_if_not_disable -> service_start

5) 循环处理事件:init进程进入无限循环,处理设备插入/拔出,服务属性状态变化和signal事件等。

while (true) {

Poll -> handle_property_set_fd -> handle_keychord -> handle_signal

}

 

这里列出默认的init.rc文件主要的事件以及服务

Action/Service

描述

on early-init

设置init进程及子进程的优先级,设置init进程的安全环境

on init

设置全局环境,为cpu accounting创建cgroup(资源控制)挂载点

on fs

挂载mtd分区

on post-fs

改变系统目录的访问权限

on post-fs-data

改变/data目录以及它的子目录的访问权限

on boot

基本网络的初始化,内存管理等等

service servicemanager

启动系统管理器管理所有的本地服务,比如位置、音频、Sharedpreference等等… 

service zygote

启动zygote作为应用进程

在这个阶段可以在设备的屏幕上看到“Androidlogo了。

 

3.2 ServiceManager

ServiceManager属于Native service。在执行init.rc时就会启动,与Zygote一样。在init.rc脚本中ServiceManager的描述:

service servicemanager /system/bin/servicemanager

所以servicemanagerframeworks/native/cmds/servicemanager/service_manager.main(..)开始

int main(int argc, char **argv)

{

    struct binder_state *bs;

// 打开/dev/binder设备,并在内存中映射128k的空间

    bs = binder_open(128*1024);

    if (!bs) {

        ALOGE("failed to open binder driver\n");

        return -1;

    }

// 通知Binder设备,把自己变成context_manger

    if (binder_become_context_manager(bs)) {

        ALOGE("cannot become context manager (%s)\n", strerror(errno));

        return -1;

    }

 

    selinux_enabled = is_selinux_enabled();

    sehandle = selinux_android_service_context_handle();

    selinux_status_open(true);

 

    if (selinux_enabled > 0) {

        if (sehandle == NULL) {

            ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");

            abort();

        }

 

        if (getcon(&service_manager_context) != 0) {

            ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");

            abort();

        }

    }

 

    union selinux_callback cb;

    cb.func_audit = audit_callback;

    selinux_set_callback(SELINUX_CB_AUDIT, cb);

    cb.func_log = selinux_log_callback;

    selinux_set_callback(SELINUX_CB_LOG, cb);

// 进入循环,不停的去读Binder设备,看是否有对service的请求,如果有就会调用svcmgr_handler函数回调处理请求

    binder_loop(bs, svcmgr_handler);

 

    return 0;

}

servicemanager中的svcmgr_handler负责处理Android中所有有关service的请求响应

int svcmgr_handler(...,...struct binder_io *reply)

{

......

    case SVC_MGR_GET_SERVICE:

    case SVC_MGR_CHECK_SERVICE:

......

case SVC_MGR_ADD_SERVICE:

......

   case SVC_MGR_LIST_SERVICES:

......

}

如在SystemServer中注册各种Android中的service时,调用的ServiceManager.addService(“entropy”,new EntropyService);即最终调用该servicemanagerSVC_MGR_ADD_SERVICE,执行do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, txn->sender_pid)接口,由servicemanager负责注册各项服务。注册后,会将该service加入svcList中。svcList中存了各个注册过的servicenamehandler

当接收到获取service的请求时,则会执行SVC_MGR_CHECK_SERVICEdo_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);...bio_put_ref(reply, handle); servicemanager会查找该service,如果存在,把返回数据写入reply,返回给客户。

 

3.3 Zygote

Servicemanagerzygote进程奠定了Android的基础。Zygote这个进程起来才会拉起真正的Android运行空间,初始化建立的service都是Native service,在.rc脚本文件中zygote的描述:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

所以zygoteframeworks/base/cmds/app_main.main(..)开始

建立java runtime

runtime.start("com.android.internal.os.ZygoteInit", args, zygote)

该函数中:

1) 创建Dalvik Java虚拟机,JNI_CreateJavaVM(...)

2) 注册Android Runtime中的JNI接口给虚拟机

3) 呼叫Javacom.android.internal.os.ZygoteInit中的main函数

Frameworks/base/core/java/com/android/internal/os/ZygoteInit.javamain中:

1) registerZygoteSocket(); // 注册listen端口,用来接收请求

2) Preload(); //预加载classresources用来加快启动速度并初始化核心内库,文件清单在framework.jar中的preloaded-class,framework-res.apk中的res中,

3) startSystemServer(); // 启动system server

4) 进入zygote服务框架

经过以上步骤zygote就建立完成,利用socket通信,接收ActivityManagerService的请求,fork应用程序。

在这个阶段,你可以看到启动动画。

 

3.4 System Server

1) startSystemServer()中通过Zygote.forkSystemServer(...) fork出独立的进程,名称为 system-serverAndroid的所有服务循环框架都建立在SystemServer上。

2) handleSystemServerProcess(...)

RuntimeInit.zygoteInit(...)

nativeZygoteInit() //最终呼叫的是AppRuntime.onZygoteInit函数

applicationInit(...) -> invokeStaticMain(...) //呼叫com.android.server.SystemServer类中的main函数

3) com.android.server.SystemServer.main中创建线程注册各种serviceservicemanager

Looper.prepareMainLooper();进入循环

System.loadLibrary("android_servers"); 首先加载android_server共享库,源码位于frameworks/base/service/jni,该库中定义jni_onload函数,Dalvik在加载libandroid_server.so时,会呼叫该函数,该函数将android server注册到java虚拟机中,如HardwareServiceAlarmService等;

startBootstrapServices();

startCoreServices();

startOtherServices();

Looper.loop();

 

核心服务:

启动电源管理器;

创建Activity管理器;

启动电话注册;

启动包管理器;

设置Activity管理服务为系统进程;

启动上下文管理器;

启动系统Context Providers

启动电池服务;

启动定时管理器;

启动传感服务;

启动窗口管理器;

启动蓝牙服务;

启动挂载服务。

其他服务:

启动状态栏服务;

启动硬件服务;

启动网络状态服务;

启动网络连接服务;

启动通知管理器;

启动设备存储监视服务;

启动定位管理器;

启动搜索服务;

启动剪切板服务;

启动登记服务;

启动壁纸服务;

启动音频服务;

启动耳机监听;

启动AdbSettingsObserver(处理adb命令)。

 

 

3.5 Home启动

SystemServer.startOtherServices()的后半段,启动完所有的Android服务后,进行如下操作:if(xxxService != null) xxxService.systemReady();通知各个服务,系统已经准备就绪。

对于mActivityManagerService.systemReady(new Runnable() {

public void run() {

startSystemUi(context);

wallpaperF.systemRunning();

...

}

}

Home就是在ActivityManagerService.systemReady通知过程中建立的。

public void systemReady(final Runnable goingCallback) {

synchronized(this) {

...

startHomeActivityLocked(mCurrentUserId, "systemReady");

...

mStackSupervisor.resumeTopActivitiesLocked();

...

}

}

startHomeActivityLocked(userId, reason){

...

Intent intent = getHomeIntent();

ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);//根据intentActionCategory信息寻找出适合启动的Activity信息,结果会返回Launcher所在的包名及类名等信息

...

mStackSupervisor.startHomeActivity(intent, aInfo, reason);

}

Intent getHomeIntent() {

Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);//新建一个intent,其中mTopActionIntent.ACTION_MAINmTopData的值为null

...

intent.addCategory(Intent.CATEGORY_HOME);

return intent;

}

void startHomeActivity(intent, aInfo, reason) {

...

startActivityLocked(...);

...

}

startActivityLocked(...){

...

//根据传入的IntentActivityInfo实例化一个ActivityRecord对象,初始化过程中会去获得该Activity的各种信息,一个ActivityRecord对象中包含了该Activity的各种信息,是HistoryStack的入口

ActivityRecord r = new ActivityRecord(...);

...

err = startActivityUncheckedLocked(r,...);

...

}

startActivityUncheckedLocked(r,...){

...

targetStack.startActivityLocked(r,...);

...

}

startActivityLocked(r,...){

...

r.putInHistory();

...

//重新调用该函数,启动处于栈顶的Activity

mStackSupervisor.resumeTopActivitiesLocked(this, r, options);

}

final ActivityRecord next = topRunningActivityLocked(null);

...

mWindowManager.setAppVisibility(next.appToken, true);

...

mStackSupervisor.startSpecificActivityLocked(next, true, true);

...

realStartActivityLocked(r, app, andResume, checkConfig);//该接口实例化一个Launcher Activity对象

...

//该接口会启动Launcher Activity进程

mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,

                "activity", r.intent.getComponent(), false, false, true, r);

...

Process.ProcessStartResult startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, app.info.dataDir, entryPointArgs);//根据app指定的uid等信息,启动对应的进程

至此Launcher进程便启动完成,完成了HOME的启动。

 

Step 7:引导完成

1. 一旦系统服务在内存中跑起来了,Android就完成了引导过程。在这个时候“ACTION_BOOT_COMPLETED”开机启动广播就会发出去