Android 启动分析-init进程&init.rc[转]  

本文转自:  http://h1372865100.blog.163.com/blog/static/210429103201292911399594/

首先是   init 进程启动

               (一些 native 服务启动)

          

           如: servicemanager 启动

                    Zygote 启动

                        SysytemServer 启动,在

                           init1

                           init2 函数中启动 Android 服务

 

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

  

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

 

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

       ...

          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.hardware ro.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 add event ,然后它可以为这个设  

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

   命令(在 onrestart )的时候                                     

*/

    。。。

    }

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

early-init

init

early-boot

boot

property:*

 

分析 init.rc 文件 @/system/core/rootdir/init.rc

 

  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

 

vold bootsound 分别是两个服务的名称, /system/bin/vold /system/bin/playmp3 分别是他们所对应的可执行程序。 socket user group 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);

 

ZygoteInit main 方法中

              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 后, Zygote forkSystemServer 之后,建立了 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

 

 

最后会调用 ActivityManagerService systemReady 方法,

依次执行

       resumeTopActivityLocked

   startHomeActivityLocked intent.addCategory(Intent.CATEGORY_HOME)

       startActivityLocked

最终启动完成进入 Home 画面

更多相关文章

  1. C语言函数的递归(上)
  2. Android(安卓)后台任务(六)IntentService
  3. android TextView实现多种颜色显示
  4. android 设置activity启动退出动画 | 解决设置activity 动画不生
  5. Android基础复习
  6. [Android(安卓)Training视频系列]6.1 Saving Key-Value Sets
  7. Android之不同Activity之间的数据传递
  8. Android(安卓)ANR 分析解决方法
  9. Android调用ITelephony类的endCall()方法 实现来电拒接

随机推荐

  1. Android捕获监听Home键、最近任务列表键
  2. android 开发之Activity切换
  3. Android(安卓)activity之间传递数据
  4. android线程池的优化
  5. android 连接指定wifi
  6. Android(安卓)SurfaceView+MediaPlayer实
  7. android上用opengl画线
  8. android Drawable 缩放
  9. android应用发短信
  10. android CoordinatorLayout里viewpager占