Android系统启动过程

首先Android框架架构图:(来自网上,我觉得这张图看起来很清晰)

  

Linux内核启动之后就到Android Init进程,进而启动Android相关的服务和应用。

启动的过程如下图所示:(图片来自网上,后面有地址)

   

  

  下面将从Android4.0源码中,和网络达人对此的总结中,对此过程加以学习了解和总结,

以下学习过程中代码片段中均有省略不完整,请参照源码。

一 Init进程的启动

  init进程,它是一个由内核启动的用户级进程。内核自行启动(已经被载入内存,开始运行,

并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程。init始终是第一个进程。

  启动过程就是代码init.c中main函数执行过程:system\core\init\init.c

在函数中执行了:文件夹建立,挂载,rc文件解析,属性设置,启动服务,执行动作,socket监听……

下面看两个重要的过程:rc文件解析和服务启动。

1 rc文件解析

  .rc文件是Android使用的初始化脚本文件 (System/Core/Init/readme.txt中有描述:

four broad classes of statements which areActions,Commands,Services, andOptions.)

  其中Command 就是系统支持的一系列命令,如:export,hostname,mkdir,mount,等等,其中一部分是 linux 命令,

还有一些是 android 添加的,如:class_start <serviceclass>: 启动服务,class_stop <serviceclass>:关闭服务,等等。

  其中Options是针对 Service 的选项的。

系统初始化要触发的动作和要启动的服务及其各自属性都在rc脚本文件中定义。 具体看一下启动脚本:\system\core\rootdir\init.rc

在解析rc脚本文件时,将相应的类型放入各自的List中:

  \system\core\init\Init_parser.c :init_parse_config_file( )存入到

  action_queue、 action_list、 service_list中,解析过程可以看一下parse_config函数,类似状态机形式挺有意思。

  这其中包含了服务:adbd、servicemanager、vold、ril-daemon、debuggerd、surfaceflinger、zygote、media……

2 服务启动

文件解析完成之后将service放入到service_list中。

文件解析完成之后将service放入到service_list中。

  \system\core\init\builtins.c

Service的启动是在do_class_start函数中完成:

int do_class_start(int nargs, char **args)
{service_for_each_class(args[1], service_start_if_not_disabled);return 0;
}

遍历所有名称为classname,状态不为SVC_DISABLED的Service启动

void service_for_each_class(const char *classname,void (*func)(struct service *svc))
{……
}static void service_start_if_not_disabled(struct service *svc)
{if (!(svc->flags & SVC_DISABLED)) {service_start(svc, NULL);}
}

do_class_start对应的命令:

  KEYWORD(class_start, COMMAND, 1, do_class_start)

init.rc文件中搜索class_start:class_start main 、class_start core、……

  main、core即为do_class_start参数classname

init.rc文件中Service class名称都是main:

service drm /system/bin/drmserver

    classmain

  service surfaceflinger /system/bin/surfaceflinger

   classmain

于是就能够通过main名称遍历到所有的Service,将其启动。

do_class_start调用:

init.rc中

    on boot  //action

      class_start core    //执行command 对应do_class_start

     class_start main

Init进程main函数中:

system/core/init/init.c中:

int main(){

     //挂在文件

//解析配置文件:init.rc……

//初始化化action queue

     ……for(;;){execute_one_command();restart_processes();for (i = 0; i < fd_count; i++) {if (ufds[i].revents == POLLIN) {if (ufds[i].fd == get_property_set_fd())handle_property_set_fd();else if (ufds[i].fd == get_keychord_fd())handle_keychord();else if (ufds[i].fd == get_signal_fd())handle_signal();}}}
}

  循环调用service_start,将状态SVC_RESTARTING启动, 将启动后的service状态设置为SVC_RUNNING。

  pid=fork();

  execve();

  在消息循环中:Init进程执行了Android的Command,启动了Android的NativeService,监听Service的变化需求,Signal处理。

Init进程是作为属性服务(Property service),维护这些NativeService。

二 ServiceManager启动

在.rc脚本文件中zygote的描述:

service servicemanager /system/bin/servicemanagerclass coreuser systemgroup systemcriticalonrestart restart zygoteonrestart restart mediaonrestart restart surfaceflingeronrestart restart drm

ServiceManager用来管理系统中所有的binder service,不管是本地的c++实现的还是java语言实现的都需要

这个进程来统一管理,最主要的管理就是,注册添加服务,获取服务。所有的Service使用前都必须先在servicemanager中进行注册。

  do_find_service( )

  do_add_service( )

  svcmgr_handler( )

  代码位置:frameworks\base\cmds\servicemanager\Service_manager.c

三 Zygote进程的启动

  Zygote这个进程是非常重要的一个进程,Zygote进程的建立是真正的Android运行空间,初始化建立的Service都是Navtive service.

(1) 在.rc脚本文件中zygote的描述:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-serverclass mainsocket zygote stream 666onrestart write /sys/android_power/request_state wakeonrestart write /sys/power/state ononrestart restart mediaonrestart restart netd参数:--zygote --start-system-server

代码位置:frameworks/base/cmds/app_process/app_main.cpp

上面的参数在这里就会用上,决定是否要启动和启动那些进程。

int main( ){AppRuntime runtime;if (zygote) {runtime.start("com.android.internal.os.ZygoteInit",startSystemServer ? "start-system-server" : "");}
}class AppRuntime : public AndroidRuntime{};

(2) 接着到了AndroidRuntime类中:

frameworks\base\core\jni\AndroidRuntime.cpp

void start(const char* className, const char* options){// start the virtual machine Java在虚拟机中运行的JNIEnv* env;if (startVm(&mJavaVM, &env) != 0) {return;}//向刚刚新建的虚拟机注册JNI本地接口if (startReg(env) < 0) {return;}// jni 调用 java 方法,获取对应类的静态main方法jmethodID startMeth = env->GetStaticMethodID(startClass,"main","([Ljava/lang/String;)V");// jni调用 java方法,调用到ZygoteInit类的main函数
jclass startClass = env->FindClass(className);env->CallStaticVoidMethod(startClass, startMeth, strArray);
}

  到了ZygoteInit.java中的静态main函数中,从C++ ——》JAVA

(3)ZygoteInit

真正Zygote进程:

frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

public static void main(String argv[]) {//Registers a server socket for zygote command connectionsregisterZygoteSocket();//Loads and initializes commonly used classes and//used resources that can be shared across processespreload();// Do an initial gc to clean up after startupgc();if (argv[1].equals("start-system-server")) {startSystemServer();}/*** Runs the zygote process's select loop. Accepts new connections as* they happen, and reads commands from connections one spawn-request's* worth at a time.*/runSelectLoopMode();    //loop中/*** Close and clean up zygote sockets. Called on shutdown and on the* child's exit path.*/closeServerSocket();
}

Zygote就建立好了,利用Socket通讯,接收请求,Fork应用程序进程,进入Zygote进程服务框架中。

四 SystemServer启动

(1)在Zygote进程进入循环之前,调用了startSystemServer( );

private static boolean startSystemServer(){/* Request to fork the system server process 孵化新的进程 */ZygoteConnection.Arguments parsedArgs = null;pid = Zygote.forkSystemServer(parsedArgs.uid, parsedArgs.gid,parsedArgs.gids,parsedArgs.debugFlags,null,parsedArgs.permittedCapabilities,parsedArgs.effectiveCapabilities);/* For child process 对新的子进程设置 */if (pid == 0) {handleSystemServerProcess(parsedArgs);}
}void handleSystemServerProcess(parsedArgs){closeServerSocket();//"system_server"Process.setArgV0(parsedArgs.niceName);//Pass the remaining arguments to SystemServer.RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,parsedArgs.remainingArgs);/* should never reach here */
}

(2)RuntimeInit中:

frameworks\base\core\java\com\android\internal\os\RuntimeInit.java

//The main function called when started through the zygote process.
void zygoteInit(int targetSdkVersion, String[] argv){applicationInit(targetSdkVersion, argv);
}void applicationInit(int targetSdkVersion, String[] argv){// Remaining arguments are passed to the start class's static maininvokeStaticMain(args.startClass, args.startArgs);
}void invokeStaticMain(String className, String[] argv){Class<?> cl;cl = Class.forName(className);//获取SystemServer的main方法,抛出MethodAndArgsCaller异常Method m;m = cl.getMethod("main", new Class[] { String[].class });int modifiers = m.getModifiers();throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

(3)从startSystemServer开始执行并没有去调用SystemServer的任何方法,

    只是通过反射获取了main方法,付给了MethodAndArgsCaller,并抛出了MethodAndArgsCaller异常。

    此异常是在哪里处理的呢?

回到startSystemServer( )函数的调用处:

在ZygoteInit的main函数中:

public static void main(String argv[]) {try {……if (argv[1].equals("start-system-server")) {startSystemServer();       //这里如果抛出异常,跳过下面流程}runSelectLoopMode();    //loop中……} catch (MethodAndArgsCaller caller) {caller.run();        //处理的异常}
}

  如果startSystemServer抛出了异常,跳过执行ZygoteInit进程的循环,这是怎么回事呢?

  在startSystemServer中异常是由handleSystemServerProcess抛出,而

      pid = Zygote.forkSystemServer( )

      /* For child process 仅对新的子进程设置 */

      if (pid == 0) {

        handleSystemServerProcess(parsedArgs);

      }

      // Zygote.forkSystemServer根据参数fork 出一个子进程,若成功调用,则返回两次:

    一次返回的是 zygote 进程的 pid ,值大于0;一次返回的是子进程 pid,值等于0否则,出错返回-1;

  caller.run();

    MethodAndArgsCaller run函数:调用前面所提到的

    //SystemServer main方法

    m = cl.getMethod("main", new Class[] { String[].class });

    启动了进程SystemServer。

(4)SystemServer的执行 init1( )

//frameworks\base\services\java\com\android\server\SystemServer.java

public static void main(String[] args) {System.loadLibrary("android_servers");    /** This method is called from Zygote to initialize the system.* This will cause the native services (SurfaceFlinger, AudioFlinger, etc..)* to be started. After that it will call back* up into init2() to start the Android services.*/init1(args);    //native 完了回调init2( )}//init1:frameworks/base/services/jni/com_android_server_SystemServer.cpp:: android_server_SystemServer_init1( )   中调用:system_init
extern "C" status_t system_init()
{sp<ProcessState> proc(ProcessState::self());sp<IServiceManager> sm = defaultServiceManager();//启动SurfaceFlinger 和传感器property_get("system_init.startsurfaceflinger", propBuf, "1");SurfaceFlinger::instantiate();property_get("system_init.startsensorservice", propBuf, "1");SensorService::instantiate();// And now start the Android runtime.  We have to do this bit// of nastiness because the Android runtime initialization requires// some of the core system services to already be started.// All other servers should just start the Android runtime at// the beginning of their processes's main(), before calling// the init function.AndroidRuntime* runtime = AndroidRuntime::getRuntime();//回调 com.android.server.SystemServer init2 方法
JNIEnv* env = runtime->getJNIEnv();jclass clazz = env->FindClass("com/android/server/SystemServer");jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");env->CallStaticVoidMethod(clazz, methodId);//启动线程池 做为binder 服务ProcessState::self()->startThreadPool();IPCThreadState::self()->joinThreadPool();return NO_ERROR;}

ProcessState:

  每个进程在使用binder 机制通信时,均需要维护一个ProcessState 实例来描述当前进程在binder 通信时的binder 状态。

  ProcessState 有如下2 个主要功能:

  1. 创建一个thread, 该线程负责与内核中的binder 模块进行通信,称该线程为Pool thread ;

  2. 为指定的handle 创建一个BpBinder 对象,并管理该进程中所有的BpBinder 对象。

Pool thread:

  在Binder IPC 中,所有进程均会启动一个thread 来负责与BD 来直接通信,也就是不停的读写BD ,

  这个线程的实现主体是一个IPCThreadState 对象,下面会介绍这个类型。

  下面是Pool thread 的启动方式:

  ProcessState::self()->startThreadPool();

IPCThreadState :

  IPCThreadState 也是以单例模式设计的。由于每个进程只维护了一个ProcessState 实例,同时ProcessState 只启动一个Pool thread ,

也就是说每一个进程只会启动一个Pool thread ,因此每个进程则只需要一个IPCThreadState 即可。

Pool thread 的实际内容则为:

IPCThreadState::self()->joinThreadPool();

(5)SystemServer的执行 init2( )

public static final void init2() {   //建立线程来处理Thread thr = new ServerThread();      thr.setName("android.server.ServerThread");thr.start();
}//看看线程ServerThread里面都做了什么事情?
public void run() {addBootEvent(new String("Android:SysServerInit_START"));Looper.prepare();android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);//初始化服务,创建各种服务实例,如:电源、网络、Wifi、蓝牙,USB等,
  //初始化完成以后加入到 ServiceManager中,//事我们用 Context.getSystemService (String name) 才获取到相应的服务PowerManagerService power = null;NetworkManagementService networkManagement = null;WifiP2pService wifiP2p = null;WindowManagerService wm = null;BluetoothService bluetooth = null;UsbService usb = null;NotificationManagerService notification = null;StatusBarManagerService statusBar = null;……power = new PowerManagerService();ServiceManager.addService(Context.POWER_SERVICE, power);……// ActivityManagerService作为ApplicationFramework最重要的服务ActivityManagerService.setSystemProcess();ActivityManagerService.installSystemProviders();ActivityManagerService.self().setWindowManager(wm);   // We now tell the activity manager it is okay to run third party
  // code.  It will call back into us once it has gotten to the state
  // where third party code can really run (but before it has actually
  // started launching the initial applications), for us to complete our
  // initialization.
  //系统服务初始化准备就绪,通知各个模块ActivityManagerService.self().systemReady(new Runnable() {public void run() {startSystemUi(contextF);batteryF.systemReady();networkManagementF.systemReady();usbF.systemReady();……// It is now okay to let the various system services start their// third party code...appWidgetF.systemReady(safeMode);wallpaperF.systemReady();}});////BOOTPROFaddBootEvent(new String("Android:SysServerInit_END"));Looper.loop();
}

  到这里系统ApplicationFramework层的XxxServiceManager准备就绪,可以开始跑上层应用了,我们的第一个上层应用HomeLauncher。

  HomeActivity又是如何启动的呢?

  Activity的启动必然和ActivityManagerService有关,我们需要去看看

  ActivityManagerService.systemReady( )中都干了些什么。

五 Home界面启动

 public void systemReady(final Runnable goingCallback) {……
    //ready callbackif (goingCallback != null)goingCallback.run();synchronized (this) {// Start up initial activity.// ActivityStack mMainStack;mMainStack.resumeTopActivityLocked(null);}
……}final boolean resumeTopActivityLocked(ActivityRecord prev) {// Find the first activity that is not finishing.ActivityRecord next = topRunningActivityLocked(null);if (next == null) {
    // There are no more activities!  Let's just start up the// Launcher...if (mMainStack) {//ActivityManagerService mService;return mService.startHomeActivityLocked();}}……
}

然后就启动了Home界面,完成了整个Android启动流程。

整个过程如下:

  

参考文档:

http://blog.csdn.net/maxleng/article/details/5508372

http://www.cnblogs.com/linucos/archive/2012/05/22/2513760.html#commentform

http://www.cnblogs.com/idiottiger/archive/2012/05/25/2516295.html

Android系统启动过程相关推荐

  1. Android 系统启动过程

    文章来源于网络,心得来源于整理. 请尊重作者:http://hi.baidu.com/guoxiaoming/blog/item/24e9e9f8c9628f1fd9f9fd89.html/cmtid ...

  2. android tcpdump log分析,android 系统启动过程中加入tcpdump和logcat

    一.android 系统启动过程中加入tcpdump ,分析开机启动后,系统与服务器端的消息交互. 1. init.rc 中的修改 1)在init.rc 中加上tcpdump service. ser ...

  3. Android系统启动过程详解

    转自:http://www.cloudchou.com/android/post-361.html 前言 一直想研究Android完整的启动过程,网上看了不少资料,也看了书上的一些说明,对这些观点有些 ...

  4. Android系统启动过程全解析

    Android系统是一款基于Linux的移动操作系统,那么Android是如何启动起来的呢?本文就详细阐述Android系统的启动过程. 从内核之上,我们首先应该从文件系统的init开始,因为 ini ...

  5. Android系统启动流程—— init进程zygote进程SystemServer进程启动流程

    原文地址:https://blog.csdn.net/qq_30993595/article/details/82714409 Android系统启动流程 Android系统启动过程往细了说可以分为5 ...

  6. 从源码解析-Android系统启动流程概述 init进程zygote进程SystemServer进程启动流程

    Android系统启动流程 启动流程 Loader Kernel Native Framework Application init进程 启动 rc文件规则 Actions Commands Serv ...

  7. 转载:一篇文章看明白 Android 系统启动时都干了什么

    最近在看<深入理解Android内核设计思想>,老实说,作为教材,这本书实在写的不好.本来内核的东西就比应用层繁杂,需要有个条绳子牵着,有个框子框着才不好跟丢.这个书老是在章节开头抛出一些 ...

  8. Android系统启动顺序(按下power键后所做的的工作)

    Android是一个基于Linux的开源操作系统.所有的Android设备都是运行在ARM处理器(ARM 源自进阶精简指令集机器,源自ARM架构)上,除了英特尔的Xolo设备(http://xolo. ...

  9. Android开发——Android系统启动以及APK安装、启动过程

    0. 前言   从Android手机打开开关,到我们可以使用其中的app时,这个启动过程到底是怎么样的? 1.  系统上电 当给Android系统上电,在电源接通的瞬间,CPU内的寄存器和各引脚均会被 ...

最新文章

  1. 使用C#调用外部Ping命令获取网络连接情况
  2. mysql connect 500_MySQL连接问题【mysql_connect和mysql_pconnect区别】
  3. Java 洛谷 P1534 不高兴的津津(升级版)
  4. oralce 异常处理 exception
  5. Apache RocketMQ部署文档
  6. python比较日期大小_Python日期的处理——datetime模块
  7. 封装 axios 请求
  8. 安全随笔2:对称加密应用场景
  9. php ip2long bug,php ip2long函数怎么用-PHP问题
  10. 大数据里的婚姻:婚后两年,出轨高峰……
  11. html设置referer防盗链,referer与防盗链
  12. 对话Pauly Comtois:赫斯特商业媒体中的企业DevOps采用
  13. 程序相关概念及OS Linux发行版
  14. 12-【istio】-【流量管理】-【流量管理原理】istio Sidecar的两种注入方式、注入原理
  15. java 定义整数数组_JAVA中数组的正确定义方法是什么?
  16. python plt绘制多子图
  17. 蓝桥杯——ALGO_971 比较_Java
  18. 前端面试题:金山办公2020校招前端开发工程师笔试题(一)
  19. 博弈论笔记--06--纳什均衡之约会游戏与古诺模型
  20. 两种主流大数据系统架构的区别,终于有人讲明白了

热门文章

  1. Unity3D中的线性插值Lerp()函数解析
  2. [详解]Linux的目录里都装些啥??
  3. asp.net控件开发基础系列
  4. javascript ~~canvas url blob转换
  5. 模拟利器Mockito
  6. 虚拟机开启Linux时出现“我以复制虚拟机”、“我已移动虚拟机”
  7. 漫漫长路十多小时,谁是机上WiFi的“业界良心”?
  8. gdal读写图像分块处理
  9. java SSL 简单操作demo
  10. 四则运算2扩展---c++