转自:http://www.cnblogs.com/bastard/archive/2012/08/28/2660389.html

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 are ActionsCommandsServices, and Options.)

  其中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

    class main

  service surfaceflinger /system/bin/surfaceflinger

   class main

于是就能够通过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/servicemanager
  class core
  user system
  group system
  critical
  onrestart restart zygote
  onrestart restart media
  onrestart restart surfaceflinger
  onrestart 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-server
  class main
  socket zygote stream 666
  onrestart write /sys/android_power/request_state wake
  onrestart write /sys/power/state on
  onrestart restart media
  onrestart 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 connections
registerZygoteSocket(); //Loads and initializes commonly used classes and
//used resources that can be shared across processes
preload(); // Do an initial gc to clean up after startup
gc(); 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 main
invokeStaticMain(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();
}
}); //
//BOOTPROF
addBootEvent(new String("Android:SysServerInit_END"));
Looper.loop();
}

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

  HomeActivity又是如何启动的呢?

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

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

五 Home界面启动

 public void systemReady(final Runnable goingCallback) {
    ……
    //ready callback
if (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系统启动过程-uBoot+Kernel+Android

    摘要:本文是参考大量网上资源在结合自己查看源代码总结出来的,让自己同时也让大家加深对Android系统启动过程有一个更加深入的了解!再次强调,本文的大多数功劳应归功于那些原创者们,同时一些必要的参考链 ...

  2. Android 系统启动过程简单记录

    本文记录Android系统启动过程,包含从linux kernerl到luancher启动完成的过程: 1.linux内核完成系统设置后,会在系统文件中寻找‘init’文件,然后启动root进程或者说 ...

  3. Android 深入浅出 - Android系统启动过程

    Activity的类继承关系及跟踪Activity的启动 Android系统启动过程 https://study.163.com/course/courseLearn.htm?courseId=213 ...

  4. Android系统启动过程[典☆☆☆]

    Android系统启动过程 首先Android框架架构图:(来自网上,我觉得这张图看起来很清晰) Linux内核启动之后就到Android Init进程,进而启动Android相关的服务和应用. 启动 ...

  5. Android系统启动过程

    首先Android框架架构图: Linux内核启动之后就到Android Init进程,进而启动Android相关的服务和应用. 启动的过程如下图所示:(图片来自网上,后面有地址)   下面将从And ...

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

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

  7. Android 系统启动过程详解

    android 使用 linux 内核,一般运行在 ARM 体系架构上,android 设备启动的过程,应用层之下基本等同于linux, 从应用层第一个程序init开始有所区别,下面开始介绍. ste ...

  8. Android系统启动分析(Init->Zygote->SystemServer->Home activity)

    整个Android系统的启动分为Linux Kernel的启动和Android系统的启动.Linux Kernel启动起来后,然后运行第一个用户程序,在Android中就是init程序. ------ ...

  9. 为什么要有uboot?带你全面分析嵌入式linux系统启动过程中uboot的作用

    1.为什么要有uboot 1.1.计算机系统的主要部件 (1)计算机系统就是以CPU为核心来运行的系统.典型的计算机系统有:PC机(台式机+笔记本).嵌入式设备(手机.平板电脑.游戏机).单片机(家用 ...

随机推荐

  1. 数据结构-二叉树(Binary Tree)

    #include <stdio.h> #include <string.h> #include <stdlib.h> #define LIST_INIT_SIZE ...

  2. Python入门必学:递归函数正确的操作使用方法,案例详解

    递归函数,在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. 举个例子,我们来计算阶乘n! = 1 x 2 x 3 x ... x n,用函数fact(n)表示,可以 ...

  3. Serializer序列器

    定义Serializer 1. 定义方法 Django REST framework中的Serializer使用类来定义,须继承自rest_framework.serializers.Serializ ...

  4. python flask学习第1天

    flask安装: 第一个flask程序: 用pycharm新建一个flask项目,新建项目的截图如下: app.py代码如下: #从flask这个包中导入Flask这个类 #Flask这个类是项目的核 ...

  5. stm32 flash和sram

    FLASH是用来存储程序的,SRAM是用来存储程序运行中的中间变量

  6. A1055 The World's Richest(25 分)

    A1055 The World's Richest(25 分) Forbes magazine publishes every year its list of billionaires based ...

  7. mysql双机热备实现

    说明 机器A:(172.16.1.251),机器B:(172.16.1.252) 两台机器都创建数据库web:create database hello default charset utf8; 实 ...

  8. Hive将SQL转化为MapReduce的过程

    Hive将SQL转化为MapReduce的过程: Antlr定义SQL的语法规则,完成SQL词法,语法解析,将SQL转化为抽象语法树AST Tree 遍历AST Tree,抽象出查询的基本组成单元Qu ...

  9. HighCharts实现双Y轴

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.c ...

  10. Python框架之Django学习笔记(十七)

    Django框架之表单(续二) 今天的这篇博客将是Django学习笔记博客的最后一篇,基本每周最少一篇的Django框架学习,坚持到今天也实属不易,当然了,这个框架的学习仅仅是Django框架的基础部 ...