首先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启动流程。

整个过程如下:

  

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系统启动过程【转】

    转自:http://www.cnblogs.com/bastard/archive/2012/08/28/2660389.html Android系统启动过程 首先Android框架架构图:(来自网上 ...

  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. eclipse中将项目发布到tomcat的root目录

    在eclipse中,将项目直接部署在tomcat的root目录中,这样便可以直接ip:port访问项目: 项目右键->属性->web project settings

  2. PE文件学习系列三-PE头详解

    合肥程序员群:49313181.    合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入) Q  Q:408365330     E-Mail:egojit@qq.com 最近比较忙 ...

  3. 关于如何在cenos7.0上实现mysql数据库远程连接

    设置mysql允许别的客户机控制的权限 mysql -uroot -p #此处为本地linux帐号密码 select user,host from mysql.user; #查看mysql表对应use ...

  4. 繁星——jquery的data()方法

    今天在看JQuery文档的时候偶然看到了data()方法,觉得挺好用的,这里做个记录. 这个方法用于在元素上存放数据,返回jQuery对象.在文档中提到V1.4.3 新增用法NEW data(obj) ...

  5. 关于EM,REM,PX的几点注意

    px是绝对单位,不支持IE的缩放,em是相对单位. em指字体高,任意浏览器的默认字体高都是16px.所以未经调整的浏览器都符合: 1em=16px.那么12px=0.75em, 10px=0.625 ...

  6. c++读书笔记, 零散点滴的收获

    1. 字节长度: short <= int <= long <= long long 2. wchar_t,最大扩展字符集合:char16_t.char32_t,unocide字符集 ...

  7. 新手要想学好Linux系统就必须做好这四件事情

    一般情况下,大部分人接触Linux的机会并不多,对Linux平台下的开发更是一无所知.而现在的发展趋势却越来越表明:无论是作为一个优秀的软件开发人员,或是互联网.IT行业的从业人员,掌握Linux是一 ...

  8. linux中用户的主目录~

    -在Linux中代表用户主目录 对一般用户,-表示/home/(用户名) 对于root用户,-表示/root 如果要查看-的真实面貌,可以先进入-目录,然后用pwd -P命令查看-的绝对路径 cd ~ ...

  9. HDU 4067 hdoj 4067 Random Maze 最小费用流

    给出n个点,m条边,入口s和出口t,对于每条边有两个值a,b,如果保留这条边需要花费:否则,移除这条边需要花费b. 题目要求用最小费用构造一个有向图满足以下条件: 1.只有一个入口和出口 2.所有路都 ...

  10. The last packet successfully received from the server was 2,926,157 milliseconds ago. The last packet sent successfully to the server was 2,926,158 milliseconds ago. is longer than the server configured value of 'wait_timeout'. 解决办法

    Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully rec ...