Android是一个基于Linux的开源操作系统。所有的Android设备都是运行在ARM处理器(ARM 源自进阶精简指令集机器,源自ARM架构)上,除了英特尔的Xolo设备(http://xolo.in/xolo-x900-features)。Xolo来源自凌动1.6GHz x86处理器。Android设备或者嵌入设备或者基于linux的ARM设备的启动过程与桌面版本相比稍微有些差别。这篇文章中,我将解释Android设备的启动过程。深入linux启动过程是一篇讲桌面linux启动过程的好文。

当你按下电源开关后Android设备执行了以下步骤。


第一步:启动电源以及系统启动

当电源按下,引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序到RAM,然后执行。

解释:设备上电起来后,跳转到Boot ROM(不是flash是SOC片上寄存器)中的boot code中执行把pre-loader加载起到ISRAM, 因为当前DRAM(RAM分SRAM跟DRAM,简单来说SRAM就是cache,DRAM就是普通内存)还没有准备好,所以要先把pre-loader load到芯片内部的ISRAM(Internal SRAM)中

我的理解:power键按下----->PMIC供电------>CPU供电------->引导芯片代码开始从预定义的地方(固化在ROM,ROM应该为CPU内部存储区域)开始执行------->加载引导程序bootloader到RAM,然后执行。


第二步:引导程序

           引导程序是在Android操作系统开始运行前的一个小程序。引导程序是运行的第一个程序,因此它是针对特定的主板与芯片的。设备制造商要么使用很受欢迎的引导程序比如redboot、uboot、qi bootloader或者开发自己的引导程序,它不是Android操作系统的一部分  对于Android整个启动过程来说,基本可以划分成三个阶段:Bootloader引导、Linux kernel启动、Android启动。引导程序是OEM厂商或者运营商加锁和限制的地方。

引导程序分两个阶段执行。第一个阶段,检测外部的RAM以及加载对第二阶段有用的程序;第二阶段,引导程序设置网络、内存等等。这些对于运行内核是必要的,为了达到特殊的目标,引导程序可以根据配置参数或者输入数据设置内核。

Android引导程序可以在\bootable\bootloader\legacy\usbloader找到。
传统的加载器包含的个文件,需要在这里说明:

  1. init.s初始化堆栈,清零BBS段,调用main.c的_main()函数;
  2. main.c初始化硬件(闹钟、主板、键盘、控制台),创建linux标签。

更多关于Android引导程序的可以在这里了解。

总结下,U-Boot调用内核之前,下面的条件必须满足:

a.  R0=0,R1为机器类型ID,参考linux/arch/arm/tools/mach-types,R2为启动参数tag列表在RAM中的基地址。

b.  CPU的工作模式必须为SVC模式,必须禁止中断(IRQS和FIRS)。

c.  数据cache和MMU必须关闭,指令cache可以打开也可以关闭。


第三步:内核

Android内核与桌面linux内核启动的方式差不多。内核启动时,设置缓存、被保护存储器、计划列表,加载驱动。当内核完成系统设置,它首先在系统文件中寻找”init”文件,然后启动root进程或者系统的第一个进程。

[

①、谈弄BOOT.img

       厂商之间做的都和原始的U-boot代码差别挺大,不过万变不离其宗,都是加载各种各样的Image到SDRAM中,不过关于CP部分的Image有的厂商是在这里加载,有的是kernel起来后来有kernel来加载,不过都需要加载的Image就是linux kernel的Image。为了方便,只讨论加载kernel Image的情况。

   

    在继续往下之前,有必要提一下几种不同格式linux kernel编译之后所产生的镜像文件,包括其各种头和ramdisk的混合,容易让人迷糊。

    ramdisk是linux内核启动过程中需要使用的一种临时文件系统,它要么单独编译成ramdisk.img(也有叫initrd或者initramfs),要么编译进内核。

    Linux编译之后最终会产生zImage文件,不过呢,为了迎合U-boot的要求,所以也有专门为U-boot的引导做一个uImage,这个只是加了一个U-boot中定义的一个head而已,用于U-boot中检查,当然前面的ramdisk.img也是需要加这个头的,头里面有这个Image的魔数,大小,类型等信息。现在的android中的u-boot也有要求加头的,他对U-boot进行了改进和优化,做成了自己的一套检查机制,所以现在android编译出来linux部分的Image的名字叫boot.img。

    这个boot.img是zImage和ramdisk.img合成之后的,而且还加了专门的头,这个head和U-boot原始的不一样,具体的源码路径可以参考:system/core/mkbootimg/。

/*

** +-----------------+

** | boot header     | 1 page

** +-----------------+

** | kernel          | n pages 

** +-----------------+

** | ramdisk         | m pages 

** +-----------------+

** | second stage    | o pages

** +-----------------+

**

** n = (kernel_size + page_size - 1) / page_size

** m = (ramdisk_size + page_size - 1) / page_size

** o = (second_size + page_size - 1) / page_size

*/

Android就没有在ramdisk和zImage上单独重复加头了,不过近期做的mtk的平台,他们有点怪,除了上面的额外信息之外,还在这二者上单独加了标志字符串,ROOTFS和KERNEL。

   

    了解了上面这些内容之后,对于从nand上加载uImage或者boot.img,都需要经过分离head进行检查,ok之后才会真正地将数据导入SDRAM。另外别忘了的是,如果ramdisk.img是单独的,那么在加载linux kernel的镜像的时候也需要将其加载进SDRAM,如果是编译到内核了,那就不用了。

   

    通常我们的uboot起来之后,我们会运行下面的命令之一来启动内核

tftp 0x30800000 uImage;bootm (地址可选)

或者

nand read 0x30800000 0x40000 0x200000 ; bootm]



②、zImage行程过程

   zImage是linux内核编译之后产生的最终文件,它的生成过程比较复杂,这里不谈编译过程,只聊聊编译的最后阶段:

    1.  arm-linux-gnu-ld用arch/arm/kernel/vmlinux.lds、arch/arm/kernel/head.o、

arch/arm/kernel/init_task.o、各子目录下的built-in.o、lib/lib.a 、arch/arm/lib/lib.a生成顶层目录下的vmlinux(根据arch/arm/kernel/vmlinux.lds来链接 0xc0008000)

 

    2.生成system.map, 置于顶层目录之下。

    3. arm-linux-gnu-objcopy,去掉顶层vmlinux两个段-R .note -R .comment

的调试信息,减小映像文件的大小,此时大概3M多,生成arch/arm/boot/Image。

 

4. gzip -f -9 < arch/arm/boot/compressed/../Image > arch/arm/boot/compressed/piggy.gz,读入arch/arm/boot/Image的内容,以最大压缩比进行压缩,生成arch/arm/boot/compressed/目录下的piggy.gz。

 

5. arm-linux-gnu-gcc,在arch/arm/boot/compressed/piggy.S文件中是直接引入piggy.gz的内容(piggy.gz其实已经是二进制数据了),然后生成arch/arm/boot/compressed/piggy.o文件。下面是piggy.S的内容

其中所选择的行就是加入了piggy.gz的内容,通过编译生成piggy.o文件,以备后面接下来的ld链接。

 

6. arm-linux-gnu-ld,在arch/arm/boot/compressed/piggy.o的基础上,加入重定位地址和参数地址的同时,加入解压缩的代码(arch/arm/boot/compressed/head.o、misc.o),最后生成arch/arm/boot/compressed目录的vmlinux,此时在解压缩代码中还含有调试信息(根据arch/arm/boot/compressed/vmlinux.lds来链接 0x0)vmlinux.lds开始处。

注意到了27行的吗?*(.piggydata)就表示需要将piggydata这个段放在这个位置,而piggydata这个段放的是什么呢?往后翻翻,看看第五步的图片,呵呵,其实就是将按最大压缩比压缩之后的Image,压缩之后叫piggy.gz中的二进制数据。

 

    7. arm-linux-gnu-objcopy,去掉解压缩代码中的调试信息段,最后生成arch/arm/boot/目录下的zImage。

   

8. /bin/sh

/home/farsight/Resources/kernel/linux-2.6.14/scripts/mkuboot.sh -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -n 'Linux-2.6.14' -d arch/arm/boot/zImage arch/arm/boot/uImage

调用mkimage在arch/arm/boot/zImage的基础上加入64字节的uImage头,和入口地址,装载地址, 最终生成arch/arm/boot/目录下的uImage文件。

   

   

    实际上zImage是经过了高压缩之后在和解压缩程序合并在一起生成的。知道了这些之后,我们就可以给linux的启动大致分成3段:zImage解压缩、kernel的汇编启动阶段、kernel的c启动阶段。

    前两个阶段因为都是汇编写成的,代码读起来晦涩难懂,内存分布复杂,涉及MMU、解压缩等众多知识。如果有对这部分感兴趣的,可以自行分析,遇到问题可以上网查资料或者找我,这里就不详细分析了。下面是第二阶段汇编启动的主线,可以了解下:

1. 确定 processor type

    2. 确定 machine type

    3. 手动创建页表 

    4. 调用平台特定的cpu setup函数,设置中断地址,刷新Cache,开启Cache

                         (在struct proc_info_list中,in proc-arm920.S)

    5. 开启mmu I、D cache ,设置cp15的控制寄存器,设置TTB寄存器为0x30004000

    6. 切换数据(根据需要赋值数据段,清bss段,保存processor ID 和 machine type

        和 cp15的控制寄存器值)

7. 最终跳转到start_kernel   

(在__switch_data的结束的时候,调用了 b start_kernel)



第四步:init进程

init是第一个进程,我们可以说它是root进程或者说有进程的父进程。init进程有两个责任,一是挂载目录,比如/sys、/dev、/proc,二是运行init.rc脚本。

  • init进程可以在/system/core/init找到。
  • init.rc文件可以在/system/core/rootdir/init.rc找到。
  • readme.txt可以在/system/core/init/readme.txt找到。

对于init.rc文件,Android中有特定的格式以及规则。在Android中,我们叫做Android初始化语言。
Android初始化语言由四大类型的声明组成,即Actions(动作)、Commands(命令)、Services(服务)、以及Options(选项)。
Action(动作):动作是以命令流程命名的,有一个触发器决定动作是否发生。
语法

1 2 3 4 on < trigger >      < command >      < command >      < command >

Service(服务):服务是init进程启动的程序、当服务退出时init进程会视情况重启服务。
语法

1 2 3 4 service < name > < pathname > [< argument >]*      < option >      < option >      ...

Options(选项)
选项是对服务的描述。它们影响init进程如何以及何时启动服务。
咱们来看看默认的init.rc文件。这里我只列出了主要的事件以及服务。
Table

Action/Service 描述
on early-init 设置init进程以及它创建的子进程的优先级,设置init进程的安全环境
on init 设置全局环境,为cpu accounting创建cgroup(资源控制)挂载点
on fs 挂载mtd分区
on post-fs 改变系统目录的访问权限
on post-fs-data 改变/data目录以及它的子目录的访问权限
on boot 基本网络的初始化,内存管理等等
service servicemanager 启动系统管理器管理所有的本地服务,比如位置、音频、Shared preference等等…
service zygote 启动zygote作为应用进程

在这个阶段你可以在设备的屏幕上看到“Android”logo了。

 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 areActions, Commands, Services, andOptions.)

  其中Command 就是系统支持的一系列命令,如:export,hostname,mkdir,mount,等等,其中一部分是 linux 命令,

还有一些是 android 添加的,如:class_start : 启动服务,class_stop :关闭服务,等等。

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

 

    classmain

 

  service surfaceflinger /system/bin/surfaceflinger

 

       classmain

 

于是就能够通过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

Init进程启动完成之后,还负责启动其他的一些重要守护进程,包括:

Usbd进程(USBDaemon):USB连接后台进程,负责管理USB连接。

adbd进程(AndroidDebugBridgeDaemon):ADB连接后台进程,负责管理ADB连接。

debuggerd进程(DebuggerDaemon):调试器后台进程,负责管理调试请求及调试过程。

rild进程(RadioInterfaceLayerDaemon):无线接口层后台进程,负责管理无线通信服务。


主要做了以下事情:

1. 重新设置子进程终止时信号SIGCHLD的处理函数。

act.sa_handler = sigchld_handler;  //调用了wait函数等待子进程退出。

act.sa_flags = SA_NOCLDSTOP;

act.sa_mask = 0;

act.sa_restorer = NULL;

sigaction(SIGCHLD, &act, 0);

 

2. 将kernel启动过程中建立好的文件系统框架mount到相应目录。

    mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755");

   …

    mount("devpts", "/dev/pts", "devpts", 0, NULL);

    mount("proc", "/proc", "proc", 0, NULL);

mount("sysfs", "/sys", "sysfs", 0, NULL);

   

3.     open_devnull_stdio(),将init进程的标准输入、输出、出错设备设置为新建的设备节点/dev/__null__。

4.     log_init(),创建并打开设备节点/dev/__kmsg__。

5.     读取并解析rc配置文件。

5.1 先从文件/sys/class/BOOT/BOOT/boot/boot_mode读出启动方式:Factory Mode, '4';ATE Factory Mode, '6'。看是否是facatory模式。

5.2 如果是的话,需要读取并解析两个文件:init.factory.rc和init.rc。

5.3 如果是正常启动,则暂时先读取init.rc。

这里在读取解析文件的时候,是以行为最小可执行单位在解析。关于书写init.rc文件的初始化脚本语言的规则,可以上网查找。解析之后并不会马上执行,而是在init进入服务循环之前统一根据其命令本身所带的条件来执行。

   

6.     导入kernel的cmdline,也就是u-boot传递给kernel的参数,查看其中是否具有androidboot.xxx(androidboot.mode、androidboot.hardware等)参数,如果有,将其保存在同名字的xxx(mode、hardware)全局变量中。这里特别说明的是hardware这个参数,从kernel中导出一部分之后,又要从/proc/cpuinfo中导出一部分来组合成完整的hardware参数,因为后面接下来会读取并解析以特定平台的rc文件。

7.     读取特定平台相关的initrc文件,如:init.mt6516.rc。

需要注意的是:对于service,这里会给每个服务建立一个struct service的结构体,全部挂入链表service_list之中,在init最后才启动。

   

8.     检查解析出来的所有命令行当中是否有属于early-init的,如果有,将其提出来加入到链表action_queue之中,马上将其执行掉。

 

9.     device_init()函数将会打开uevent的netlink socket,遍历/sys/class、/sys/block、/sys/devices目录,检查各级目录的uevent文件,处理在vold服务起来之前由kernel所发出来的device add, remove等事件。

 

10.  property_init(), 顾名思义,是属性初始化。首先创建一个名字为system_properties的匿名共享内存区域,对并本init进程做mmap读写映射,其余共享它的进程只有读的权限。然后将这个prop_area结构体通过全局变量__system_property_area__传递给property services。

接着调用函数load_properties_from_file(PROP_PATH_RAMDISK_DEFAULT)从/default.prop文件中加载编译时生成的属性。

       

11.  如果在root目录下有initlogo.rle文件存在,这个是两张android字样的缕空图片,将其读入fb中显示到LCD上。同时也要往串口上输出"             A N D R O I D "。如果图片不存在,就没有这两项的输出。

 

12.  设置相应的属性:

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);

 

13.  开始执行以init为trigger的命令行:

action_for_each_trigger("init", action_add_queue_tail);

drain_action_queue();

        前面有执行过eraly-init的。

       

14.  启动属性服务:property_set_fd = start_property_service();

先读取剩余三个文件中的属性:/system/build.prop、/system/default.prop、/system/default.prop,然后用函数load_persistent_properties()加载persist.开始的属性,这种属性都是保存在目录/data/property下的以属性名为文件名的中。

接下来创建一个名为property_service的socket接口(SOCK_STREAM),然后进入监听状态,等待属性事件到来。

   

15.  创建一对socket,用来做信号方面的处理。

socketpair(AF_UNIX, SOCK_STREAM, 0, s),signal_fd = s[0],signal_recv_fd = s[1]。

 

    16.执行eraly-boot和boot为trigger的命令

        action_for_each_trigger("early-boot", action_add_queue_tail);

        action_for_each_trigger("boot", action_add_queue_tail);

        drain_action_queue();

       

17.执行init.rc中以property:开头的属性设置语句,同时使能属性触发方式。

queue_all_property_triggers();

drain_action_queue();

       

        property_triggers_enabled = 1;  //  可以执行那些以属性为条件的init语句。

       

1.     接下来就是利用poll机制监听前面创建的几个fd的动态。

struct pollfd ufds[4];

ufds[0].fd =device_fd;

ufds[0].events = POLLIN;

ufds[1].fd =property_set_fd;

ufds[1].events = POLLIN;

ufds[2].fd =signal_recv_fd;

ufds[2].events = POLLIN;

 

for(;;) {

     int nr, i, timeout = -1;

           

    for (i = 0; i < fd_count; i++)

        ufds[i].revents = 0;

    

     drain_action_queue(); //执行action_queue链表中后来新出现的command。

     restart_processes();  // 第一次启动所有服务,也包括后来restart这些

服务。restart_service_if_needed() à service_start(svc, NULL) à fork()

    

     …

     nr = poll(ufds, fd_count, timeout);

     if (nr <= 0)

            continue;

    

     if (ufds[2].revents == POLLIN) {

            /* we got a SIGCHLD - reap and restart as needed */

            read(signal_recv_fd, tmp, sizeof(tmp));

            while (!wait_for_one_process(0))

                ;

            continue;

     }

    

     if (ufds[0].revents == POLLIN)

          handle_device_fd(device_fd);  // Vold的netlink类型的socket

    

     if (ufds[1].revents == POLLIN)

          handle_property_set_fd(property_set_fd);//属性服务的socket

     if (ufds[3].revents == POLLIN)

            handle_keychord(keychord_fd);

}

到这里init就进入了死循环中一直在监听ufds中的4个文件描述符的动静,如果有POLLIN的事件,就做相应的处理,所以init并没有退出或者进入idle,而是被当做一个服务在运行。第4个文件描述符是keychord_fd,暂时不清楚这个怎么用,不过通过它也可以启动服务,可参考源码。

下面是init.rc的例子,见附件init.rc

       

二、init中启动的各种服务

在init中启动起来的服务按照init.rc中的先后顺序,大致有:

console: start a shell,code path: system/bin/sh,其源码中包含常用的shell命令,如ls,cd等。

adbd: start adb daemon,通常带有disabled的选项,表明需要按名字启动,code path:system/bin/adb。

servicemanager:这个服务管理着系统内所有binder services。code path: frameworks/base/cmds/servicemanager。

Vold: android 的udev,code path: system/vold。

Netd: start ntd daemon, code path: system/netd。

Debuggerd: start debug system, code path: system/core/debuggerd。

zygote: ['zaigəut]这是一个非常重要的服务,稍后详解。start Android  JavaRuntime  and start systemserver。code path:frameworks/base/cmds/app_process。

media: add AudioFlinger,AudioPolicyService,MediaPlayerService and CameraService to servicemanager,同时启动管理binder通讯的机制,依靠这两个类来完成binder机制在android中间层所体现的功能:ProcessState 和IPCThreadState。Code path:frameworks/base/media/mediaserver。

bootanim: 开机动画和铃声,code path:frameworks/base/cmds/bootanimation。

 

接下来就是关于modem的服务,如:ccci_fsd、ccci_mdinit、pppd_gprs、pppd、gsm0710muxd、muxtestapp、sockcli、socksrv、muxreport、ril-daemon等,除了前面2个,后面的都带有disabled的参数,需要按名启动。

 

Installd: start install package daemon, code path:

frameworks/base/cmds/installd。

后面还有很多关于其他硬件的服务,比如BT、WIFI等。

 

2.1 servicemanager

    这个服务进程代码比较简单,功能也简单,c实现的,用来管理系统中所有的binder service,不管是本地的c++实现的还是Java语言实现的都需要这个进程来统一管理,最主要的管理就是,注册添加服务,获取服务。

    这些binder服务在对外公开之前都必须将自身拥有的binder实体注册到SMgr中,而其他进程如果需要使用binder service的功能,也必须先经过SMgr取得 binder service中的binder实体在SMgr中对应的引用号(binder的引用号和进程中文件描述符概念类似,有效范围只限于本进程)。

 

#define BINDER_SERVICE_MANAGER ((void*) 0)  

int main(int argc, char **argv) 

    struct binder_state *bs; 

    void *svcmgr = BINDER_SERVICE_MANAGER;  

    bs = binder_open(128*1024);   

    // 打开binder设备,mmap映射当前进程的binder接收缓冲区,返回一个binder_state结构体  。

    if (binder_become_context_manager(bs)) {     

    // 通过这个函数将当前进程设置成服务管理进程MSgr,整个系统就这一个。 

       …

    } 

    svcmgr_handle = svcmgr;    

    binder_loop(bs, svcmgr_handler);  

 /*svcmgr_handler作为处理函数,所能完成的操作有:获取service,查看service是否存在,添加service ,列出service清单。其中用的最多的就是获取、添加。*/ 

    return 0; 

}

   


第五步

在Java中,我们知道不同的虚拟机实例会为不同的应用分配不同的内存。假如Android应用应该尽可能快地启动,但如果Android系统为每一个应用启动不同的Dalvik虚拟机实例,就会消耗大量的内存以及时间。因此,为了克服这个问题,Android系统创造了”Zygote”。Zygote让Dalvik虚拟机共享代码、低内存占用以及最小的启动时间成为可能。Zygote是一个虚拟器进程,正如我们在前一个步骤所说的在系统引导的时候启动。Zygote预加载以及初始化核心库类。通常,这些核心类一般是只读的,也是Android SDK或者核心框架的一部分。在Java虚拟机中,每一个实例都有它自己的核心库类文件和堆对象的拷贝。

Zygote加载进程

  1. 加载ZygoteInit类,源代码:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
  2. registerZygoteSocket()为zygote命令连接注册一个服务器套接字。
  3. preloadClassed “preloaded-classes”是一个简单的包含一系列需要预加载类的文本文件,你可以在/frameworks/base找到“preloaded-classes”文件。
  4. preloadResources() preloadResources也意味着本地主题、布局以及android.R文件中包含的所有东西都会用这个方法加载。

在这个阶段,你可以看到启动动画。



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进程服务框架中。

 


    zygote服务进程也叫做孵化进程,在linux的用户空间,进程app_process会做

一些zygote进程启动的前期工作,如,启动runtime运行时环境(实例),参数分解,设置startSystemServer标志,接着用runtime.start()来执行zygote服务的代码,其实说简单点,就是zygote抢了app_process这个进程的躯壳,改了名字,将后面的代码换成zygote的main函数,这样顺利地过度到了zygote服务进程。这样我们在控制台用ps看系统所有进程,就不会看到app_process,取而代之的是zygote。

       

        而前面runtime.start()这个函数实际上是类函数AndroidRuntime::start(),在

这个函数中,会新建并启动一个虚拟机实例来执行com.android.internal.os.ZygoteInit这个包的main函数。这个main函数中会fork一个子进程来启动systemserver,父进程就作为真正的孵化进程存在了,每当系统要求执行一个 Android应用程序,Zygote就会收到socket消息FORK出一个子进程来执行该应用程序。因为Zygote进程是在系统启动时产生的,它会完成虚拟机的初始化,库的加载,预置类库的加载和初始化等操作,而在系统需要一个新的虚拟机实例时可以快速地制造出一个虚拟机出来。

   

    每一个Android应用都运行在一个Dalvik虚拟机实例里,而每一个虚拟机实例都是一个独立的进程空间。虚拟机的线程机制,内存分配和管理,Mutex等等都是依赖底层linux实现的。所以android应用程序中创建了线程将会实际调用到linux的线程创建接口,和虚拟机所在进程共享一个虚拟机实例对java代码执行。

   

2.2.1 app_process

下面重点讨论zygote服务,源码位于frameworks/base/cmds/app_process。

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

参数:/system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

 

int main(int argc, const char* const argv[])

{

    …

    AppRuntime runtime; // 这里启动runtime运行时环境(实例),AppRuntime是AndroidRuntime的子类,在创建这个对象的时候会依次调用基类和子类的构造函数。

    const char *arg;

    const char *argv0;

    …

    argv0 = argv[0];

    // ignore argv[0]

    argc--;

argv++;

/*

    argc = 4;

argv[0] = “-Xzygote”;

argv[1] = “/system/bin”;

argv[2] = “--zygote”;

argv[3] = “–start-system-server”;

*/

    int i = runtime.addVmArguments(argc, argv); // 找到参数中第一个不是以单个-开始的参数,这里很明显是第二个参数:/system/bin

    if (i < argc) {

        runtime.mParentDir = argv[i++];  // 将命令目录保存在mParentDir中,之后i = 2。

    }

    if (i < argc) {

        arg = argv[i++];

        if (0 == strcmp("--zygote", arg)) { // 通常这个分支是成立的

            bool startSystemServer = (i < argc) ?

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

// startSystemServer = true ,这个bool变量决定着后面执行runtime.start时是否启动systemserver。

            setArgv0(argv0, "zygote");

            set_process_name("zygote");

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

                startSystemServer);

        } else {

            … // 只启动AndroidRuntime

        }

    }else{

        … // 错误处理

    }

} // main()

   

   2.2.2 AndroidRuntime

    下面进一步分析

    runtime.start("com.android.internal.os.ZygoteInit",startSystemServer);

    位于文件frameworks/base/core/jni/ AndroidRuntime.cpp,类定义于:

    frameworks/base/include/android_runtime/AndroidRuntime.h

    void AndroidRuntime::start(const char* className,

const bool startSystemServer){

LOGD("\n>>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<\n");

    JNIEnv* env;

    …

    /* start the virtual machine , mJavaVM是类AndroidRuntime的私有变量,env该函数中局部变量 */

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

        goto bail;

 

    /* Register android functions.向刚刚新建的虚拟机注册JNI本地接口。frameworks/base/core/jni/这个目录下的所有jni接口。*/

    if (startReg(env) < 0) {

        …

goto bail;

}

 

//启动虚拟机之前需要构造java形式的参数数组,如下:

jclass stringClass;

jobjectArray strArray;

    jstring classNameStr;

    jstring startSystemServerStr;

 

stringClass = env->FindClass("java/lang/String");

strArray = env->NewObjectArray(2, stringClass, NULL);

classNameStr = env->NewStringUTF(className);

env->SetObjectArrayElement(strArray, 0, classNameStr);

startSystemServerStr = env->NewStringUTF(startSystemServer ?

                                                 "true" : "false");

env->SetObjectArrayElement(strArray, 1, startSystemServerStr);

/*  strArray[0] = “com.android.internal.os.ZygoteInit”

    strArry[1] = “true”*/

 

/*

 * Start VM.  This thread becomes the main thread of the VM, and will

 * not return until the VM exits.

 */

jclass startClass;

jmethodID startMeth;

 

slashClassName = strdup(className);

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

    if (*cp == '.')

        *cp = '/';  // 将包名换成路径

 

startClass = env->FindClass(slashClassName); // 根据路径找到这个包

            // com.android.internal.os.ZygoteInit,这个类位于文件

            // com/ndroid/nternal/os/ZygoteInit.java

if (startClass == NULL) {

     LOGE("JavaVM unable to locate class '%s'\n", slashClassName);

     /* keep going */

 } else {

        /*这个参数决定了我们接下来执行的是zygoteInit.java的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);

                // 虚拟机启动,将会调用到com.android.internal.os.ZygoteInit包的main函数。

}

}

 

LOGD("Shutting down VM\n");

    if (mJavaVM->DetachCurrentThread() != JNI_OK)

        LOGW("Warning: unable to detach main thread\n");

    if (mJavaVM->DestroyJavaVM() != 0)

        LOGW("Warning: VM did not shut down cleanly\n");

 

bail:

    free(slashClassName);

}

} // start()

   

   2.2.3 ZygoteInit

    下面进入com.android.internal.os.ZygoteInit 包的main函数:

    frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

    public static void main(String argv[]) {

        try {

            …

            registerZygoteSocket(); // Registers a server socket for zygote command

            // load classs and resources

    preloadClasses();

    preloadResources();

    …

    // Do an initial gc to clean up after startup

gc();/*初始化GC垃圾回收机制*/

 

/* 通过从前面传递过来的第二个参数startsystemserver=”true” 启动systemserver, 在startSystemServer()中会fork一个新的进程命名为system_server, 执行的是com.android.server包中的SystemServer.java文件中的main函数, 源码位置:frameworks/base/services/java/com/android/server/ SystemServer.java。*/

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

                startSystemServer(); ///*************

} else if(…)

 

if (ZYGOTE_FORK_MODE) {

    runForkMode();      /* ZYGOTE_FORK_MODE 永远为flase */

} else {

    runSelectLoopMode();/* Zygote进程进入无限循环,不再返回。接下来的zygote将会作为一个孵化服务进程来运行。*/

}

 

closeServerSocket();

}

        …

    } // end main()

   

从这里开始android启动分为两条线走,分别是:

startSystemServer(); ---------- Zygote的子进程

runSelectLoopMode(); /* Zygote进程进入无限循环,不再返回,执行孵化工作。*/

 

2.2.4 systemserver

    上面的startSystemServer()函数中,做了如下的调用:

    startSystemServer()

    à Zygote.forkSystemServer()

    à 父进程直接返回true,子进程执行handleSystemServerProcess()

        à RuntimeInit.zygoteInit(parsedArgs.remainingArgs);

        /*

         * Pass the remaining arguments to SystemServer.

         * "--nice-name=system_server com.android.server.SystemServer"

         */

/*上面这个RuntimeInit包定于于文件frameworks\base\core\java\com\android\internal\os\RuntimeInit.java */

à invokeStaticMain(startClass, startArgs)

/* 通过该函数调用执行startClass类的main函数,带参数 system_server 。*/

à ZygoteInit.MethodAndArgsCaller(m, argv)

/* 得到包com.android.server.SystemServer的main()函数。然后执行。*/

   

    下面就开始调用到com.android.server.SystemServer类的main函数,源码位于:

    frameworks/base/services/java/com/android/server/SystemServer.java 

   

This method is called from Zygote to initialize the system. This will cause the nativeservices (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call backup into init2() to start the Android services.

    //main--->init1(system_init)--->init2(systemThread)

native public static void init1(String[] args);

       

public static void main(String[] args) {

        ...

System.loadLibrary("android_servers");// libandroid_servers.so是由目录frameworks/base/services/jni下的源码编译所得

init1(args); // init1实际上是一个jni本地接口,位于文件frameworks\base\services\jni\com_android_server_SystemServer.cpp文件中system_init()函数

}

   

init1接口位于com_android_server_SystemServer.cpp中:

extern "C" int system_init();

static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz){

    system_init();

}

 

static JNINativeMethod gMethods[] = {

    /* name, signature, funcPtr */

{"init1","([Ljava/lang/String;)V",(void*)

android_server_SystemServer_init1 },

};

而函数system_init()位于文件

frameworks\base\cmds\system_server\library\System_init.cpp

extern "C" status_t system_init()

{

    …

    char propBuf[PROPERTY_VALUE_MAX];

    property_get("system_init.startsurfaceflinger", propBuf, "1");

    if (strcmp(propBuf, "1") == 0) {

        // Start the SurfaceFlinger

        SurfaceFlinger::instantiate();

    }

    if (!proc->supportsProcesses()) {

       

        // Start the AudioFlinger

        AudioFlinger::instantiate();

       

        // Start the media playback service

        MediaPlayerService::instantiate();

       

        // Start the camera service

        CameraService::instantiate();

       

        // Start the audio policy service

        AudioPolicyService::instantiate();

       

        //start appc service

        APPCService::instantiate();

    }

    …

    AndroidRuntime* runtime = AndroidRuntime::getRuntime();

    runtime->callStatic("com/android/server/SystemServer", "init2");

    // 执行com.android.server.SystemServer类的init2函数

}

com.android.server.SystemServer包的init2函数开启一个ServerThread线程:

public static final void init2() {

    Thread thr = new ServerThread();

    thr.setName("android.server.ServerThread");

    thr.start();

}

ServerThread线程的run函数会启动系统中绝大部分的android service,并最后进入Loop.loop(),,,,(SystemServer.java)

public void run() {

    …

    // Critical services...

    try {

        …

        Slog.i(TAG, "Power Manager");

        power = new PowerManagerService();

        ServiceManager.addService(Context.POWER_SERVICE, power);

       

        Slog.i(TAG, "Activity Manager");

        context = ActivityManagerService.main(factoryTest);

       

        …

        Slog.i(TAG, "Package Manager");

        pm = PackageManagerService.main(context,

                factoryTest != SystemServer.FACTORY_TEST_OFF);

       

        …

        Slog.i(TAG, "Content Manager");

        ContentService.main(context,

             factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);

       

        …

        Slog.i(TAG, "Battery Service");

        battery = new BatteryService(context);

        ServiceManager.addService("battery", battery);

        …

        其余addservice的过程类似,只是启动的不同服务罢了,后面还启动了很多

服务,如:Lights、Vibrator、Alarm、Sensor、Bluetooth、Input Method、NetStat、NetworkManagement、Connectivity、Mount、Notification、Audio等。在这些服务都启动完了之后。

        …

        …

        … // run()函数的后半部分

        // It is now time to start up the app processes...

        使用xxx.systemReady()通知各个服务,系统已经就绪。

        …

        ((ActivityManagerService)ActivityManagerNative.getDefault())

                .systemReady(new Runnable() {

         public void run() {

                …

                if (batteryF != null) batteryF.systemReady();

                if (connectivityF != null) connectivityF.systemReady();

                if (dockF != null) dockF.systemReady();

                if (uiModeF != null) uiModeF.systemReady();

                if (recognitionF != null) recognitionF.systemReady();

                Watchdog.getInstance().start();

                …

            }

        });

        …

        Looper.loop(); // Run the message queue in this thread。

        …

}

 

2.2.5 home界面启动

    Home在

((ActivityManagerService)ActivityManagerNative.getDefault()).systemReady(.)

函数调用的过程中启动,其中systemReady()的参数是一段callback代码,如上面灰色显示的部分。

这个函数的实现部分在文件:ActivityManagerService.java中。

public void systemReady(final Runnable goingCallback) {

    …

   

    if (mSystemReady) {

        if (goingCallback != null) goingCallback.run();

        return; // 执行回调

    }

    …

    resumeTopActivityLocked(null);

}

private final boolean resumeTopActivityLocked(HistoryRecord prev) {

    …

    if (next == null) {

        // There are no more activities!  Let's just start up the

        // Launcher...

        return startHomeActivityLocked();

    }

    …

}

private boolean startHomeActivityLocked() {

    …

    if (aInfo != null) {

        …

        if (app == null || app.instrumentationClass == null) {

                intent.setFlags(intent.getFlags() |

                                Intent.FLAG_ACTIVITY_NEW_TASK);

                startActivityLocked(null, intent, null, null, 0, aInfo,

                        null, null, 0, 0, 0, false, false); // 这里启动home

         }

     }

    …

}


第六步:系统服务或服务

完成了上面几步之后,运行环境请求Zygote运行系统服务。系统服务同时使用native以及java编写,系统服务可以认为是一个进程。同一个系统服务在Android SDK可以以System Services形式获得。系统服务包含了所有的System Services。

Zygote创建新的进程去启动系统服务。你可以在ZygoteInit类的”startSystemServer”方法中找到源代码。

核心服务:

  1. 启动电源管理器;
  2. 创建Activity管理器;
  3. 启动电话注册;
  4. 启动包管理器;
  5. 设置Activity管理服务为系统进程;
  6. 启动上下文管理器;
  7. 启动系统Context Providers;
  8. 启动电池服务;
  9. 启动定时管理器;
  10. 启动传感服务;
  11. 启动窗口管理器;
  12. 启动蓝牙服务;
  13. 启动挂载服务。

其他服务:

  1. 启动状态栏服务;
  2. 启动硬件服务;
  3. 启动网络状态服务;
  4. 启动网络连接服务;
  5. 启动通知管理器;
  6. 启动设备存储监视服务;
  7. 启动定位管理器;
  8. 启动搜索服务;
  9. 启动剪切板服务;
  10. 启动登记服务;
  11. 启动壁纸服务;
  12. 启动音频服务;
  13. 启动耳机监听;
  14. 启动AdbSettingsObserver(处理adb命令)。


(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_initextern "C" status_t system_init(){       sp proc(ProcessState::self());       sp 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( )中都干了些什么。


第七步:引导完成

一旦系统服务在内存中跑起来了,Android就完成了引导过程。在这个时候“ACTION_BOOT_COMPLETED”开机启动广播就会发出去。

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

Android的启动过程可以分为两个阶段,第一阶段是Linux的启动,第二阶段才是Android的启动,下面我们分别来了解一下具体的过程。

首先是Linux启动,这一部分我想就可以略过了,无非是Linux的Bootloader,Kernel,Driver之类的,在这里唯一要提到 的就是ServiceManager,即服务管理器,这个是做为一个进程在Android加载之前就被启动了,我们可以从init.rc中看到这个配置 项:

service servicemanager /system/bin/servicemanager

ServiceManager是Binder的服务管理守护进程,是Binder的核心,由其使用Binder驱动进行IPC管理,关于IPC通讯 的机制,此处不再详述。在APP和Framework中,应用程序使用的ServiceManager.java就是通过Proxy与这个守护进程进行的 通讯。

然后是Android的启动,接下来要详细描述的部分。我们还是先看一下init.rc中的配置

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

即linux启动以后,启动zygote服务进程,这个进程恰如其名:孵化器,是所有Android应用程序的孵化器。

我们来看一下app_process的代码,位置是在:

frameworks/base/cmds/app_process/app_main.cpp

在main()函数中有如下代码:

        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);         }

从中可以追踪到AndroidRuntime,代码位于:

frameworks/base/core/jni/AndroidRuntime.cpp

在start()函数中有如下代码:

    /* start the virtual machine */    if (startVm(&mJavaVM, &env) != 0)        goto bail;         ……     env->CallStaticVoidMethod(startClass, startMeth, strArray);

即先启动了虚拟机,然后利用JNI调用了zygoteInit函数。

继续追踪到frameworks/base/core/java/com/android/internal/os/ZygoteInit.java的main()函数,代码如下:

    if (argv[1].equals("true")) {startSystemServer();    } else if (!argv[1].equals("false")) {throw new RuntimeException(argv[0] + USAGE_STRING);    }    Log.i(TAG, "Accepting command socket connections");    if (ZYGOTE_FORK_MODE) {runForkMode();    } else {runSelectLoopMode();    }

前一部分是在启动系统服务,后一部分是虽然是一个条件判断,但ZYGOTE_FORK_MODE被赋了false,所以进行else分支的 runSelectLoopMode()函数,在该函数中,实际上是在一死循环中利用zygoteConnection类通过socket的方式进行消息 处理,用于fork出新的zygote,从而以最轻量级的方式实现每个进程一个虚拟机的机制。

继续来看startSystemServer(),代码位于:

frameworks/base/services/java/com/android/server/systemserver.java

在其main()函数中调用了init1(args)这个native函数,利用JNI机制,跟踪至

frameworks/base/services/jni/com_android_server_systemService.cpp,然后到

frameworks/base/cmds/system_server/library/system_init.cpp

在system_init()函数中有如下代码

    if (strcmp(propBuf, "1") == 0) {        // Start the SurfaceFlinger        SurfaceFlinger::instantiate();    }     AndroidRuntime* runtime = AndroidRuntime::getRuntime();     LOGI("System server: starting Android services./n");     runtime->callStatic("com/android/server/SystemServer", "init2");

即完成了SurfaceFlinger的实例化,然后利用运行时的callStatic()函数调用了SystemServer的init2()函数,这个函数位于:

frameworks/base/services/java/com/android/server/SystemServer.java

代码是:

public static final void init2() {        Slog.i(TAG, "Entered the Android system server!");        Thread thr = new ServerThread();        thr.setName("android.server.ServerThread");        thr.start();}

在这个ServerThread线程中,可以看到我们熟悉的Android服务了,比如WallpaperService服务的启动:

try {Slog.i(TAG, "Wallpaper Service");wallpaper = new WallpaperManagerService(context);ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);} catch (Throwable e) {Slog.e(TAG, "Failure starting Wallpaper Service", e);}

最后,调用各服务的systemReady()函数通知系统就绪。

至此,系统的启动过程结束

从这里可以看出,linux的init在启动若干守护进程之后,就启动了Android的runtime和zygote,zygote再启动虚拟机,系统 服务,系统服务再启动完本地服务后,又启动了若干Android服务,并完成向ServiceManager的注册工作,最后系统启动完成。系统的进程空 间如下图所示:

可见,由zygote孵化器为各进程以写时复制的方式用最小的代价实现了虚拟机。

至此,系统的启动过程结束,借用两张图来说明问题:

从这里可以看出,linux的init在启动若干守护进程之后,就启动了Android的runtime和zygote,zygote再启动虚拟机,系统服务,系统服务再启动完本地服务后,又启动了若干Android服务,并完成向ServiceManager的注册工作,最后系统启动完成。系统的进程空间如下图所示:

可见,由zygote孵化器为各进程以写时复制的方式用最小的代价实现了虚拟机。


另一篇文章:

一直想研究Android完整的启动过程,网上看了不少资料,也看了书上的一些说明,对这些观点有些怀疑,于是自己分析了系统启动的完整过程。从内核启动第一个用户程序init开始说起,直到Home应用的启动,每一步都有源代码展示。希望能解除读者对Android系统启动过程中的困惑,若有什么疑问,欢迎留言交流。本研究基于CM10.1源码,读者若能对照源代码查看效果会更好。

1) init启动servicemanager和 zygote两个service

Android底层是Linux内核,和linux类似,内核初始化后启动的第一个用户进程是init,它会解析init.rc脚本,启动init.rc里声明的service,并执行一些action。在init.rc里有启动Andriod空间的一些关键服务,代码如下:

#…service servicemanager /system/bin/servicemanager    class core    user system    group system    critical    onrestart restart zygote    onrestart restart media    onrestart restart surfaceflinger    onrestart restart drmservice zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server    class main    socket zygote stream 660 root system    onrestart write /sys/android_power/request_state wake    onrestart write /sys/power/state on    onrestart restart media    onrestart restart netd#…

servicemanager负责管理所有的binder service, 这些binder service有native的,也有java的。native的binder service有surfaceflinger,drm,media等,java的binder service就有我们平常熟悉的很多管理服务了,ActivityManagerService,WindowManagerService,BatteryService,PowerManagerService,InputManagerService等等。service manager并不负责这些binder service的创建,native的binder service大多由init启动init.rc里的service时创建并启动,java层的binder service大多由zygote创建并启动的,接下来会详细这些service是如何被启动的。

2) zygote service启动java层的ZygoteInit

zygote服务是java层所有程序进程的父进程,它是Android空间程序的孵化器,Android空间所有程序都是由zygote进程启动的。zygote service对应/system/bin/app_process程序,源代码位于frameworks/base/cmds/app_process/app_main.cpp,启动时的main函数代码如下:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
int main(int argc, const char* const argv[]){//.../*runtime就是dalvik虚拟机实例,启动Java层应用时, *会fork 一个子进程,复制虚拟机,许多书上将runtime看作一个进程, *然后再启动zygote进程,个人觉得这是错误的  */\t\t AppRuntime runtime;//... while (i < argc) {    const char* arg = argv[i++];    if (!parentDir) {        parentDir = arg;  /*init.rc启动app_main会设置参数--zygote*/     } else if (strcmp(arg, "--zygote") == 0) {        zygote = true;        niceName = "zygote"; //进程的名字  /*init.rc启动app_main会设置参数--start-system-server,   *表示需启动systemserver   */    } else if (strcmp(arg, "--start-system-server") == 0) {        startSystemServer = true; /*启动应用时会使用--application参数*/                 } else if (strcmp(arg, "--application") == 0) {        application = true;/*--nice-name=参数表示要设置的进程名字*/                } else if (strncmp(arg, "--nice-name=", 12) == 0) {        niceName = arg + 12;    } else {        className = arg;        break;    }}    /*设置进程名*/if (niceName && *niceName) {    setArgv0(argv0, niceName);    set_process_name(niceName);}/*设置虚拟机运行环境的父目录*/runtime.mParentDir = parentDir;if (zygote) {/*虚拟机里启动com.android.internal.os.ZygoteInit, *并传递参数start-system-server */    runtime.start("com.android.internal.os.ZygoteInit",            startSystemServer ? "start-system-server" : "");} else if (className) {            /*若不是zygote,则启动的第一个类是com.android.internal.os.RuntimeInit,     *RumtimeInit初始化后会启动mClassName     */    runtime.mClassName = className;    runtime.mArgC = argc - i;    runtime.mArgV = argv + i;    runtime.start("com.android.internal.os.RuntimeInit",            application ? "application" : "tool");} else {    fprintf(stderr, "Error: no class name or --zygote supplied.\\n");    app_usage();    LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");    return 10;}//...}

通过上述代码可知道zygote service将运行dalvik虚拟机,并在虚拟机里执行com.android.internal.os.ZygoteInit,还给它传递了参数start-system-server

3) ZygoteInit启动SystemServer

ZygoteInit启动时的相关源代码:

12345678910111213141516171819202122232425262728293031323334
public static void main(String argv[]) {{try {      //...   //在某个描述符上监听连接请求,   //其它Android空间的程序的启动都是通过连接zygote才孵化出来的   registerZygoteSocket();   //...    if (argv[1].equals("start-system-server")) {        //启动SystemServer        startSystemServer();    } else if (!argv[1].equals("")) {        throw new RuntimeException(argv[0] + USAGE_STRING);    }   //...   /*ZYGOTE_FORK_MODE默认为false,如果为true的话,每收到一个连接请求,    *就会建立一个新进程,然后再运行连接请求所要求执行的命令,此时会建立另一个新进程    */    if (ZYGOTE_FORK_MODE) {        runForkMode();    } else {       //使用Select poll的方式来建立新进程,收到连接请求后,也会建立进程启动某个程序        runSelectLoopMode();    }    closeServerSocket();} catch (MethodAndArgsCaller caller) {    caller.run();} catch (RuntimeException ex) {    Log.e(TAG, "Zygote died with exception", ex);    closeServerSocket();    throw ex;}}

从上述代码可知道会调用startSystemServer以启动SystemServer,相关源代码如下:

1234567891011121314151617181920212223242526272829303132333435363738394041424344
private static boolean startSystemServer(){/* Hardcoded command line to start the system server *///启动SystemServer使用的参数String args[] = {    "--setuid=1000",    "--setgid=1000",    "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,3001,3002,3003,3004,3006,3007,3009",    "--capabilities=130104352,130104352",    "--runtime-init",    "--nice-name=system_server",    //注意:就是在这里设置要启动的SystemServer包名及类名,故此后续才能启动SystemServer    "com.android.server.SystemServer",};ZygoteConnection.Arguments parsedArgs = null;int pid;try {    /*将args参数传给ZygoteConnection进行转化,--形式的参数将全部被接收     * 但是要启动的类的类名com.android.server.SystemServer会放在     *ZygoteConnection.Arguments的remainingArgs里,后来调用handleSystemServerProcess时会用到     */    parsedArgs = new ZygoteConnection.Arguments(args);     /*添加额外运行参数*/    ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);    ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);     /*开启新进程*/    pid = Zygote.forkSystemServer(            parsedArgs.uid, parsedArgs.gid,            parsedArgs.gids,            parsedArgs.debugFlags,            null,            parsedArgs.permittedCapabilities,            parsedArgs.effectiveCapabilities);} catch (IllegalArgumentException ex) {    throw new RuntimeException(ex);} /* For child process */if (pid == 0) {\t  /*调用handleSystemServerProcess会执行ZygoteConnection.Arguments的remainingArgs参数\t   *所指定的类,即com.android.server.SystemServer\t   \t   */    handleSystemServerProcess(parsedArgs);}}

ZygoteInit的startSystemServer会调用forkSystemServer,然后:

ZygoteInit.forkSystemServer -> Zygote.nativeForkSystemServer-> dalvik_system_Zygote.cpp 里的Dalvik_dalvik_system_Zygote_forkSystemServer-> forkAndSpecializeCommon->fork建立新进程

ZygoteInit的startSystemServer会调用handleSystemServerProcess来真正启动systemserver,相关源代码如下:

12345678910111213141516171819
private static void handleSystemServerProcess(            ZygoteConnection.Arguments parsedArgs)            throws ZygoteInit.MethodAndArgsCaller {//... if (parsedArgs.niceName != null) {    Process.setArgV0(parsedArgs.niceName);}//启动systemserver时invokeWith为nullif (parsedArgs.invokeWith != null) {    WrapperInit.execApplication(parsedArgs.invokeWith,            parsedArgs.niceName, parsedArgs.targetSdkVersion,            null, parsedArgs.remainingArgs);} else {    /*     * 启动systemserver时,parsedArgs.remainingArgs为com.android.server.SystemServer.     */    RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);}}

然后的流程是

RuntimeInit.zygoteInit-> applicationInit,applicationInit的代码如下所示:

12345678910111213141516
private static void applicationInit(int targetSdkVersion, String[] argv){//...final Arguments args;try {    //参数转换,系统启动时,argv里有一个参数是com.android.server.SystemServer    args = new Arguments(argv);} catch (IllegalArgumentException ex) {    Slog.e(TAG, ex.getMessage());    // let the process exit    return;}//...//终于在此启动了SystemServerinvokeStaticMain(args.startClass, args.startArgs)}

4) SystemServer 启动过程

执行com.android.server.SystemServer时,main函数里会调用init1函数,init1函数是一个本地函数,init1的实现放在frameworks/base/services/jni/com_android_server_SystemServer.cpp里,对应的jni函数是android_server_SystemServer_init1,在该函数里会调用system_init,而system_init的实现是在frameworks/base/cmds/system_server/library/system_init.cpp,该函数的实现代码如下所示:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
extern "C" status_t system_init(){//... sp<ProcessState> proc(ProcessState::self());sp<IServiceManager> sm = defaultServiceManager();ALOGI("ServiceManager: %p\\n", sm.get());sp<GrimReaper> grim = new GrimReaper();sm->asBinder()->linkToDeath(grim, grim.get(), 0);char propBuf[PROPERTY_VALUE_MAX];property_get("system_init.startsurfaceflinger", propBuf, "1");if (strcmp(propBuf, "1") == 0) {    // Start the SurfaceFlinger    SurfaceFlinger::instantiate();}property_get("system_init.startsensorservice", propBuf, "1");if (strcmp(propBuf, "1") == 0) {    // Start the sensor service    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.ALOGI("System server: starting Android runtime.\\n");AndroidRuntime* runtime = AndroidRuntime::getRuntime();ALOGI("System server: starting Android services.\\n");JNIEnv* env = runtime->getJNIEnv();if (env == NULL) {    return UNKNOWN_ERROR;}jclass clazz = env->FindClass("com/android/server/SystemServer");if (clazz == NULL) {    return UNKNOWN_ERROR;}//反过来调用Java里SystemServer的init2函数jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");if (methodId == NULL) {    return UNKNOWN_ERROR;}env->CallStaticVoidMethod(clazz, methodId);ALOGI("System server: entering thread pool.\\n");ProcessState::self()->startThreadPool();IPCThreadState::self()->joinThreadPool();ALOGI("System server: exiting thread pool.\\n");}

5) 启动Java层的各种binder service

调用SystemServer的init2函数后,会开启新线程android.server.ServerThread,在新线程里会启动各种Java层的binder service,并在service manager里注册,这些Service大多开启了新线程运行,故此都是systemserver的子线程,添加的Service列表如下所示:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
ServiceManager.addService("entropy", new EntropyMixer());ServiceManager.addService(Context.POWER_SERVICE, power);ServiceManager.addService(Context.DISPLAY_SERVICE, display, true);ServiceManager.addService("telephony.registry", telephonyRegistry);ServiceManager.addService(Context.SCHEDULING_POLICY_SERVICE,ServiceManager.addService(Context.USER_SERVICE,UserManagerService.getInstance());ServiceManager.addService(Context.ACCOUNT_SERVICE, accountManager);ServiceManager.addService("battery", battery);ServiceManager.addService("vibrator", vibrator);ServiceManager.addService(Context.ALARM_SERVICE, alarm);ServiceManager.addService(Context.WINDOW_SERVICE, wm);ServiceManager.addService(Context.INPUT_SERVICE, inputManager);ServiceManager.addService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, bluetooth);ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,new AccessibilityManagerService(context));ServiceManager.addService("mount", mountService);ServiceManager.addService("lock_settings", lockSettings);ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, devicePolicy);ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);ServiceManager.addService(Context.CLIPBOARD_SERVICE,new ClipboardService(context));ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);ServiceManager.addService(Context.TEXT_SERVICES_MANAGER_SERVICE, tsms);ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);ServiceManager.addService(Context.WIFI_P2P_SERVICE, wifiP2p);ServiceManager.addService(Context.WIFI_SERVICE, wifi);ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);ServiceManager.addService(Context.NSD_SERVICE, serviceDiscovery);ServiceManager.addService(Context.THROTTLE_SERVICE, throttle);ServiceManager.addService("fm_receiver",new FmReceiverService(context));ServiceManager.addService("fm_transmitter",new FmTransmitterService(context));ServiceManager.addService(Context.UPDATE_LOCK_SERVICE,new UpdateLockService(context));ServiceManager.addService(Context.PROFILE_SERVICE, profile);ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification);ServiceManager.addService(DeviceStorageMonitorService.SERVICE,ServiceManager.addService(Context.LOCATION_SERVICE, location);ServiceManager.addService(Context.COUNTRY_DETECTOR, countryDetector);ServiceManager.addService(Context.SEARCH_SERVICE,new SearchManagerService(context));ServiceManager.addService(Context.DROPBOX_SERVICE,new DropBoxManagerService(context, new File("/data/system/dropbox")));ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);ServiceManager.addService(Context.AUDIO_SERVICE, new AudioService(context));ServiceManager.addService(Context.USB_SERVICE, usb);ServiceManager.addService(Context.SERIAL_SERVICE, serial);ServiceManager.addService(Context.BACKUP_SERVICE,new BackupManagerService(context));ServiceManager.addService(Context.APPWIDGET_SERVICE, appWidget);ServiceManager.addService("diskstats", new DiskStatsService(context));ServiceManager.addService("samplingprofiler", new SamplingProfilerService(context));ServiceManager.addService("commontime_management", commonTimeMgmtService);ServiceManager.addService(DreamService.DREAM_SERVICE, dreamy);ServiceManager.addService("assetredirection", new AssetRedirectionManagerService(context));ServiceManager.addService("pieservice", pieService);

上述并没有看到将ActivityManagerService添加到servicemanager管理,它的添加过程比较特别。在线程android.server.ServerThread里会调用ActivityManagerService.setSystemProcess();setSystemProcess函数的代码如下所示:

1234567891011121314151617
public static void setSystemProcess() {//…ActivityManagerService m = mSelf;            ServiceManager.addService("activity", m, true);ServiceManager.addService("meminfo", new MemBinder(m));ServiceManager.addService("gfxinfo", new GraphicsBinder(m));ServiceManager.addService("dbinfo", new DbBinder(m));if (MONITOR_CPU_USAGE) {    ServiceManager.addService("cpuinfo", new CpuBinder(m));}ServiceManager.addService("permission", new PermissionController(m));ApplicationInfo info =    mSelf.mContext.getPackageManager().getApplicationInfo(                "android", STOCK_PM_FLAGS);mSystemThread.installSystemApplicationInfo(info);//…}

可以看到ActivityManagerService采用了单例模式,并调用ServiceManager.addService("activity", m, true);将ActivityManagerService交给servicemanager管理,在ActivityManagerService里还添加了别的binder service,像MemBinder,GraphicsBinder,DbBinder。

最后会调用Looper.loop();进入loop循环,等待和别的程序通信。

6) 启动系统界面

线程android.server.ServerThread里有如下代码:

12345678
ActivityManagerService.self().systemReady(new Runnable() {    public void run() {        Slog.i(TAG, "Making services ready");        if (!headless) startSystemUi(contextF);        //...     }}

startSystemUi就是用于启动系统界面的,代码如下:

1234567
static final void startSystemUi(Context context) {        Intent intent = new Intent();        intent.setComponent(new ComponentName("com.android.systemui",                    "com.android.systemui.SystemUIService"));        //Slog.d(TAG, "Starting service: " + intent);        context.startServiceAsUser(intent, UserHandle.OWNER);}

这样便启动了com.android.systemui应用,该应用将启动PowerUI和RingtonePlayer两个线程。

7) 启动Home 程序

线程android.server.ServerThread里有如下代码:

1234567
//…ActivityManagerService.self().systemReady(new Runnable() {            public void run() {                  //…                }    });//…

ActivityManagerService.self().systemReady有如下代码:

123
//…mMainStack.resumeTopActivityLocked(null);//…

ActivityStack. resumeTopActivityLocked()有如下代码:

1
resumeTopActivityLocked(prev, null);

resumeTopActivityLocked的实现有如下代码:

12345678910
//…if (next == null) {    // There are no more activities!  Let's just start up the    // Launcher...    if (mMainStack) {        ActivityOptions.abort(options);         return mService.startHomeActivityLocked(mCurrentUser);    }}//…

mService类型是ActivityManagerService,ActivityManagerService. startHomeActivityLocked的实现有如下代码:

1234567891011121314151617181920212223242526272829
boolean startHomeActivityLocked(int userId) {//…Intent intent = new Intent(    mTopAction,    mTopData != null ? Uri.parse(mTopData) : null);intent.setComponent(mTopComponent);//这里便添加了Intent.CATEGORY_HOME,//所有的Home应用都会都带有该类型的Activity,只有这样才会被认为是Home应用if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {    intent.addCategory(Intent.CATEGORY_HOME);}ActivityInfo aInfo =    resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);if (aInfo != null) {    intent.setComponent(new ComponentName(            aInfo.applicationInfo.packageName, aInfo.name));    // Don't do this if the home app is currently being    // instrumented.    aInfo = new ActivityInfo(aInfo);    aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);    ProcessRecord app = getProcessRecordLocked(aInfo.processName,            aInfo.applicationInfo.uid);    if (app == null || app.instrumentationClass == null) {        intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);        mMainStack.startActivityLocked(null, intent, null, aInfo,                null, null, 0, 0, 0, 0, null, false, null);    }}}

这样先找到使用Intent.CATEGORY_HOME声明的Activity组件,然后再调用mMainStack.startActivityLocked启动该Activity。

system server启动Home程序总结:

android.server.ServerThread->ActivityManagerService.self().systemReady->mMainStack.resumeTopActivityLocked->resumeTopActivityLocked-> mService.startHomeActivityLocked-> intent.addCategory(Intent.CATEGORY_HOME);mMainStack.startActivityLocked

总结

内核初始化好后,运行的第一个用户程序是init,init将启动init.rc里声明的多个service,跟Android空间相关的有servicemanager和zygote,servicemanager负责管理所有的binder service,zygote负责孵化所有Android空间的程序。zygote service对应的程序是app_process,不过加了一些启动参数,所以它会启动Java层的ZygoteInit,在ZygoteInit里会启动SystemServer,SystemServer分为两个阶段:本地的init1和Java层的init2,init2里会启动线程android.server.ServerThread。在android.server.ServerThread线程里会启动Java层的各种binder service,比如ActivityManagerService,PackageManagerService,WindowManagerService。然后调用ActivityManagerService的systemReady方法,在该方法里会启动系统界面以及Home程序。



更多相关文章

  1. C语言函数的递归(上)
  2. Android中hybrid开发的基础知识
  3. Android(安卓)Studio配置文件修改
  4. Android对象序列化(Activity之间传递对象,Parcelable小例子)
  5. 3G应用开发之Android(安卓)传智播客 基础知识总结
  6. Android(安卓)Gradle系列-入门篇
  7. kill掉android应用的bat
  8. 【Android】Android(安卓)线程&进程模型
  9. Android应用程序结构--比较偏的考试题目

随机推荐

  1. 详解Mysql基础语法的使用
  2. 数据库性能测试之sysbench工具的安装与用
  3. MySQL8新特性:持久化全局变量的修改方法
  4. MySQL8新特性:降序索引详解
  5. MySQL8新特性:自增主键的持久化详解
  6. MySQL root密码忘记后更优雅的解决方法
  7. 升级到MySQL5.7后开发不得不注意的一些坑
  8. 阿里云云服务器mysql密码找回的方法
  9. 关于MySQL中的查询开销查看方法详解
  10. MySQL存储结构用法案例分析