Android系统启动过程【转】

转自: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

 

分类: AndroidAndroid FrameWork

标签: Android 启动过程

时间: 2024-09-27 04:10:09

Android系统启动过程【转】的相关文章

Android启动过程深入解析

当按下Android设备电源键时究竟发生了什么? Android的启动过程是怎么样的? 什么是Linux内核? 桌面系统linux内核与Android系统linux内核有什么区别? 什么是引导装载程序? 什么是Zygote? 什么是X86以及ARM linux? 什么是init.rc? 什么是系统服务? 当我们想到Android启动过程时,脑海中总是冒出很多疑问.本文将介绍Android的启动过程,希望能帮助你找到上面这些问题的答案. Android是一个基于Linux的开源操作系统.x86(x

android 启动过程

android系统启动的时候首先会启动Linux的基础进程,加载Linux kernel启动初始化(init)进程. 接着,回启动Linux deamon(守护进程)会启动以下的内容: ①启动USBdusb管理守护进程来管理USB连接. ②启动adb守护进程来管理adb连接 ③启动debugged守护进程来管理调试程序请求. ④启动ridle守护进程来管理无线管理进程. 请看图: 在启动init进程会启动守护进程同时,同时还会启动一个zygnote进程,其步骤如下: ①初始化一个davilk虚拟

Android启动过程的分析

本文讲的是Android启动过程的分析, 大多数智能手机用户使用的Android操作系统的功能和操作过程都比较复杂. 对于Android操作系统的初学者来说,引导过程,只不过是终端用户的一些花哨的图像和动画.但当你阅读完这篇文章后,你可能会打破原来对引导过程的狭隘思维. 基本核心过程 引导ROM >引导加载程序 >内核 > init过程> Zygote > Dalvik V M >系统服务器 >管理器 该过程是Android启动的核心过程,下面让我来详细介绍每一步

Android系统启动阶段多种快速重启系统方法试验记录

Android系统启动阶段多种快速重启系统方法试验记录             笔者的系统是android4.2 A20平台,平台使用的是ext4文件系统.按我以前的经验对于nand来说yaffs对系统突然断电重启会好很多.笔者一个应用需求就是,系统启动到kernel,但是还没到应用能处理倒车事件的时候,笔者需要快速重启,让系统进入boot来完成倒车功能,这也是为了快速响应倒车影像.笔者使用了好几种重启系统的方法,都有一些问题,有的系统虽然能重启,但是因为文件系统由于突然掉电可能导致一些cash

FreeBSD系统启动过程

当使用安装程序Sysinstall完成了系统安装和基本配置任务之后,系统需要重新启动.在系统从硬盘上重新启动之后,一个完好的FreeBSD系统就展现在使用者面前了.系统将出现登录提示,允许使用者登录进入FreeB SD操作系统. Unix是一种多用户.多任务的操作系统,它支持并能管理多个用户使用系统,其用户分为普通用户和管理员两类.普通用户只能使用系统提供的具体应用功能,而只有管理员才能更改系统的配置.维护整个系统.FreeBSD系统的拥有者不但是仅仅使用系统的普通用户,同样也是整个系统的管理员

jenkins 远程构建Android的过程详解_Android

由于企业的需求,需要做一个网站开分享每个版本的Android的app,所以需要使用的工具如下: Jenkins平台,远程编译环境服务器一台,web服务器一台,根据自己的选择,可以搭配自己的资源,废话少说,直奔主题 1. Jenkins的操作 在Jenkins中添加一个节点,设置好远程的工作目录,创建好服务器的标签,然后创建好相关的环境键值对,比如Android_home,Java_home,Gradle_home等,这些都是比较平常的操作,这里就不罗嗦了,值得注意的有两点:第一,java的路径问

Linux操作系统启动过程详解

如果你对Linux操作系统有一定的了解,想对其更深层次的东西做进一步探究.这当中就包括系统的启动流程.文件系统的组成结构.基于动态库和静态库的程序在执行时的异同.协议栈的架构和原理.驱动程序的机制等等. 其中Linux操作系统启动过程肯定是大家最有兴趣了解的,这里在综合了现有网上大家智慧的基础上,基于2.6.32的内核的CentOS 6.0系统,对Linux的启动流程做了些分析,希望对大家有所帮助. OK,我们言归正传.对于一台安装了Linux系统的主机来说,当用户按下开机按钮时,一共要经历以下

《Android的设计与实现:卷I》——第1章 Android体系结构及源代码阅读环境搭建 1.1 Android发展过程

第1章 Android体系结构及源代码阅读环境搭建 Android是Google于2007年11月5日发布的基于Linux内核的开源移动设备软件平台,该平台由操作系统.虚拟机.运行库.框架.应用软件以及开发工具组成. 1.1 Android发展过程 Android自 Android 1.5开始,以甜点作为平台版本代号,并且各代号首字母以C D E F G H I J顺序排列.Android自发布以来,经过数个版本的更新和完善,已成为最大的智能手机平台之一.Android的发展过程如表 截至201

如何调试系统启动过程中systemd的代码

之前写过很多kernel的gdb debug, 其实用户态也是可以调试的, 只是在共享库的动态地址上不是很好处理, 最近同事有调试系统启动过程中systemd的需求, 简单研究了一下 其实qemu kvm打断点并不区别kernel还是用户态, 都是rip的值等于某个地址或者遇到断点指令了, 所以开机的时候把断点打到systemd的main上就可以了 但是其实另外一个问题是, 用户态的地址是很多进程共享的, 这时候有可能会另一个进程也跑到了这个地址, 所以断点就需要条件断点, 用进程的pid是一个