Android 启动分析 init进程 init.rc

转自:http://blog.csdn.net/SkyGray/archive/2010/06/25/5694898.aspx

 

       前段时间看了下Android的启动的源代码,大致的理了下,很多底层的一些机制,实现什么都没过多的研究。对于Android架构理解有很大的帮助

---------------------------------------------------------------------------------------------------------

首先是  init进程启动

              (一些native服务启动)

          

           如:servicemanager启动

                   Zygote启动

                       SysytemServer启动,在

                          init1

                          init2函数中启动Android服务

 

init进程起来后,解析init.rcinit.xxx.rc建立基本的服务

  

之后进入循环,并没有退出

 

分析init.c@/system/core/initmain函数主要实现过程

      ...

        mkdir("/dev", 0755)  //创建具有可读写的目录/dev

     。。。

     log_init();     //初始化log系统

      。。。     

    parse_config_file("/init.rc");   /*解析init.rc文件,parse_config_file这个          函数是在/system/core/init/parse.c这个类中实现的,讲解析得到的service信息储存到

service_list这个数据解构中*/

    

    get_hardware_name();

    snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);

    parse_config_file(tmp);   /*解析init.xxx.rc,和硬件相关*/

 

    action_for_each_trigger("early-init", action_add_queue_tail);

    drain_action_queue();     /*执行解析得到的”early-init”的action*/

   

    INFO("device init/n");

    device_fd = device_init(); /*设备的初始化。挂载结点倒/dev下还有下载

                               firmwares*/

 

    property_init();          

    。。。                   /*property初始化*/

 

      /*读取/initlogo.rle(一张位图),如果成功则在/dev/graphics/fb0显示Logo,如果失败则将/dev/tty0,设为TEXT模式并打开/dev/tty0,输出文本ANDROID。具体实现可看

   /system/core/init/log.c

   */

   if( load_565rle_image(INIT_IMAGE_FILE) ) {  

   fd = open("/dev/tty0", O_WRONLY);

   if (fd >= 0) {

      。。。

      。。。

    }

    /*判断cmdline中的參數,并设置属性系统中的参数:

   * 1如果 bootmode

   *    - factory,设置ro.factorytest值为1

   *    - factory2,设置ro.factorytest值为2

   *    -其他的設ro.factorytest值為0

   * 2、如果有serialno参数,则设置ro.serialno,否则为""

   * 3、如果有bootmod参数,则设置ro.bootmod,否则为"unknown"

   * 4、如果有baseband参数,则设置ro.baseband,否则为"unknown"

   * 5、如果有carrier参数,则设置ro.carrier,否则为"unknown"

   * 6、如果有bootloader参数,则设置ro.bootloader,否则为"unknown"

   * 7、通过全局变量(前面从/proc/cpuinfo中提取的)设置ro.hardwarero.version

   */

   if (qemu[0])

       import_kernel_cmdline(1);

 

   if (!strcmp(bootmode,"factory"))

       property_set("ro.factorytest", "1");

   else if (!strcmp(bootmode,"factory2"))

       property_set("ro.factorytest", "2");

   else

       property_set("ro.factorytest", "0");

 

   property_set("ro.serialno", serialno[0] ? serialno : "");

   property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown");

   property_set("ro.baseband", baseband[0] ? baseband : "unknown");

   property_set("ro.carrier", carrier[0] ? carrier : "unknown");

   property_set("ro.bootloader", bootloader[0] ? bootloader : "unknown");

 

   property_set("ro.hardware", hardware);

   snprintf(tmp, PROP_VALUE_MAX, "%d", revision);

   property_set("ro.revision", tmp);

 

 

 

    action_for_each_trigger("init", action_add_queue_tail);

    drain_action_queue();    /*执行解析得到的init action */

 

    property_set_fd = start_property_service(); //启动 property service

    。。。

    。。。                  

       /*sigchld handler创建信号机制*/

   

  if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0) {

       signal_fd = s[0];

       signal_recv_fd = s[1];

       fcntl(s[0], F_SETFD, FD_CLOEXEC);

       fcntl(s[0], F_SETFL, O_NONBLOCK);

       fcntl(s[1], F_SETFD, FD_CLOEXEC);

       fcntl(s[1], F_SETFL, O_NONBLOCK);

   }

 

   /*确认所有初始化工作完成

    * device_fd(device init完成)

    * property_set_fd(property server start完成)

    * signal_recv_fd (信号机制建立)

    */

   if ((device_fd < 0) ||

       (property_set_fd < 0) ||

       (signal_recv_fd < 0)) {

       ERROR("init startup failure/n");

       return 1;

   }

 

   action_for_each_trigger("early-boot", action_add_queue_tail);

   action_for_each_trigger("boot", action_add_queue_tail);

   drain_action_queue();            //执行解析的"early-boot""boot"action

 

   queue_all_property_triggers();

   drain_action_queue();     //执行解析的property action

 

   for(;;){

   。。。             

/*

  进入无限循环

  等待一些device/property set/process eixt这些event

  比如SD插入时,会收到device addevent,然后它可以为这个设 

  备添加节点。处理一些process exit event,执行在*.rc中定义的

  命令(在onrestart)的时候                                    

*/

   。。。

   }

从上可以看出init依次执行五种触发器(Triggers

early-init

init

early-boot

boot

property:*

 

分析init.rc文件@/system/core/rootdir/init.rc (语法:system/core/init/readme.txt)

 

 1 .关于init.rc

Android中使用启动脚本init.rc,可以在系统的初始化过程中进行一些简单的初始化操作。这个脚本被直接安装到目标系统的根文件系统中,被init可执行程序解析。 init.rc是在init启动后被执行的启动脚本,其余发主要包含了以下内容:

   * Commands:命令

   * Actions:动作

   * Triggers:触发条件

   * Services:服务

   * Options:选项

   * Propertise:属性

Commands是一些基本的操作,例如:

   mkdir /sdcard 0000 system system
   mkdir /system
   mkdir /data 0771 system system
   mkdir /cache 0770 system cache
   mkdir /config 0500 root root
   mkdir /sqlite_stmt_journals 01777 root root
   mount tmpfs tmpfs /sqlite_stmt_journals size=4m
这些命令在 init 可执行程序中被解析,然后调用相关的函数来实现。
 

Actions(动作)表示一系列的命令,通常在Triggers(触发条件)中调用,动作和触发条件例如:

   on init
   export PATH /sbin:/system/sbin:/system/bin:/system/xbin

init表示一个触发条件,这个触发事件发生后,进行设置环境变量和建立目录的操作称为一个“动作”

Services(服务)通常表示启动一个可执行程序,Options(选项)是服务的附加内容,用于配合服务使用。

service vold /system/bin/vold
   socket vold stream 0660 root mount
 
service bootsound /system/bin/playmp3
   user media
   group audio
   oneshot

voldbootsound分别是两个服务的名称,/system/bin/vold/system/bin/playmp3分别是他们所对应的可执行程序。

socketusergrouponeshot就是配合服务使用的选项.

oneshot选项表示该服务只启动一次,而如果没有oneshot选项,这个可执行程序会一直存在----如果可执行程序被杀死,则会重新启动。


Properties(属性)是系统中使用的一些值,可以进行设置和读取。

   setprop ro.FOREGROUND_APP_MEM 1536
   setprop ro.VISIBLE_APP_MEM 2048
   start adbd

setprop用于设置属性,on property可以用于判断属性,这里的属性在整个Android系统运行中都是一致的

 

init.rc启动的服务

1.console           

2.adbd         adb deamon   

                可以通过property_set persist.service.adb.enable来控制其执行

                          

3.servicemanager   启动binder system.IPC机制通信相关的吧。。。

4.vold

5.nexus

6.mountd

7.debuggerd

8.ril-daemon

9.zygote

10.media

11.bootsound

12.bootanim

13.dbus

14.bluetoothd

15.hfag

16.hsag

17.opush

18.pbap

19.installd

20.flash_recovery

21.racoon

22.mtpd

23.keystore

24.dumpstate

      

Zygote服务的启动:

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

      app_main.cpp@/framework/base/cmds/app_process/main函数中

 

      

       // Next arg is startup classname or "--zygote"

   if (i < argc) {

       arg = argv[i++];

       if (0 == strcmp("--zygote", arg)) {

           bool startSystemServer = (i < argc) ?

                   strcmp(argv[i], "--start-system-server") == 0 : false;

           setArgv0(argv0, "zygote");

           set_process_name("zygote");

           runtime.start("com.android.internal.os.ZygoteInit",  

               startSystemServer);

       } else {

           set_process_name(argv0);

 

           runtime.mClassName = arg;

 

           // Remainder of args get passed to startup class main()

           runtime.mArgC = argc-i;

           runtime.mArgV = argv+i;

 

           LOGV("App process is starting with pid=%d, class=%s./n",

                getpid(), runtime.getClassName());

           runtime.start();

       }

   } else {

       LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");

       fprintf(stderr, "Error: no class name or --zygote supplied./n");

       app_usage();

       return 10;

   }

 

 创建AppRuntime对象 runtime,执行runtime.start("com.android.internal.os.ZygoteInit",  

               startSystemServer)的方法,实现在AndroidRuntime.cpp中。

void AndroidRuntime::start(const char* className, const bool startSystemServe

{

      。。。

   /* start the virtual machine */

   if (startVm(&mJavaVM, &env) != 0)

       goto bail;

 

   /*

    * Register android functions.

    */

   if (startReg(env) < 0) {

       LOGE("Unable to register all android natives/n");

       goto bail;

   }

      。。。

}

创建虚拟机器,注册android jni方法,然后就是定位className的类

 slashClassName = strdup(className);

   for (cp = slashClassName; *cp != '/0'; cp++)

       if (*cp == '.')

           *cp = '/';

 

   startClass = env->FindClass(slashClassName);

执行该类的main方法

 startMeth = env->GetStaticMethodID(startClass, "main",

           "([Ljava/lang/String;)V");

       if (startMeth == NULL) {

           LOGE("JavaVM unable to find main() in '%s'/n", className);

           /* keep going */

       } else {

           env->CallStaticVoidMethod(startClass, startMeth, strArray);

 

ZygoteInitmain方法中

             SamplingProfilerIntegration.start();             // Start profiling the zygote                                                                                                  initialization.

             RegisterZygoteSocket();                         //注册Zygote端口

             //load preload classes路径/frameworks/base/preloaded-classes

       preloadClasses();                                                       

             //load preload resource系统常用的资源                

       preloadResources();

/*

             startSystemServer()中调用 Zygote.forkSystemServer这个nitive方法,具体实现在dalvik/vm/native/dalvik_system_Zygote.c

*/

             if (argv[1].equals("true")) {

               startSystemServer();

           }

/*

      之后进入 runSelectLoopMode

*/

       if (ZYGOTE_FORK_MODE) {

               runForkMode();

           } else {

               runSelectLoopMode()

 

startSystemServer后,ZygoteforkSystemServer之后,建立了SystemServer进程,执行其main函数,

      //load android_servers.so

      System.loadLibrary("android_servers");

      

/*执行init1 native 方法。实现在/frameworks/base/cmds/system_server/library/system_init.cpp

      1.如果是运行在模拟器上则instantiate AudioFlinger MediaPlayerService CameraService AudioPolicyService

      2.调用runtime->callStatic("com/android/server/SystemServer", "init2") SystemServer中的init2方法,

      3.如果不是运行在模拟器上,则执行

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

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

      

*/   

systemServer init2中会创建一个线程来启动所有的Android服务

1.Entropy Service

2.Power Manager

3.Activity Manager

4.Telephony Registry

5.Package Manager

6.Account Manager

7.Content Manager

8.System Content Providers

9.Battery Service

10.Hardware Service

11.Alarm Manager

12.Sensor Service

13.Window Manager

14.Bluetooth Service

15.Status Bar

16.Clipboard Service

17.Input Method Service

18.NetStat Service

19.Connectivity Service

20.Accessibility Manager

21.Notification Manager

22.Mount Service

23.Device Storage Monitor

24.Location Manager

25.Search Service

26.Checkin Service

27.Wallpaper Service

28.Audio Service

29.Headset Observer

30.Dock Observer

31.Backup Service

32.AppWidget Service

 

 

最后会调用ActivityManagerServicesystemReady方法,

依次执行

      resumeTopActivityLocked

  startHomeActivityLockedintent.addCategory(Intent.CATEGORY_HOME)

      startActivityLocked

最终启动完成进入Home画面

 

你可能感兴趣的:(android,init)