Android源码学习

 

Android源码

下载

2018-2-4

直接使用清华大学的镜像【注意不能使用VMware + Ubuntu + 共享文件夹的方式,主要英文共享文件夹不支持linux某些文件】

https://mirrors.tuna.tsinghua.edu.cn/help/AOSP/

 

目录结构

2018-2-5

http://blog.csdn.net/itachi85/article/details/54695046

详细目录结构

http://blog.csdn.net/ieearth/article/details/64930164

 

编译

从网上下载的android源码不包括u-boot和linux内核,需要下载对应的版本,然后在编译。

 

android启动流程

在学习启动流程时,首先打印Android的启动日志,打印方法参见:Android内核开发:如何统计系统的启动时间

先贴一张图:

2018-2-6

Android 的底层基于 Linux Kernel,因此从启动流程来看,先启动 Linux Kernel,然后才启动 Android Framework,最后进入应用程序 Launcher,也就是看到的主界面。因此可将Android的启动流程分为下面3个阶段:

 

第一阶段:Linux内核启动

主要参考:Android笔记 - Android启动之Linux内核启动

这一阶段有分为三个过程:

(1)机器上电,进入Bootrom

Bootrom 是固化在芯片中的一小段程序,主要功能是上电时完成硬件自检,然后从固定分区加载 Bootloader。Bootrom 的功能相当于 PC 上的 BIOS,Bootloader 的功能相当于 PC 上的 GRUB。这个程序一般是硬件厂商做的,Android手机厂商不会修改。

(2)Bootloader初始化软硬件环境 ,

Bootloader 是在进入 Linux Kernel 之前运行的程序。Android 采用的 Bootloader 实现方式是 Uboot。手机厂商一般会定制化Bootloader程序,这程序的主要作用是检测硬件,加载linux kernel。

(3)启动 Linux Kernel ,

这一阶段和标准 Linux Kernel 启动过程基本一致。Kernel 加载进内存后会进行自解压。自解压完成后,继续进行一些平台相关的初始化,然后开始 start_kernel 函数,它的实现代码位于 init/main.c 中。

以上分析基于 linux-4.4.52内核,至此,linux内核分析完毕。这里的“/init”进程是用户空间中的额第一个进程。

备注:我们知道,linux内核的系统有固定的流程,一般内核启动完毕后,就是加载用户的程序,用户的程序一般放在某个脚本中(好像是“/etc/init/init.rc”文件),执行脚本中的每一行语句,即开启相应的进程。

以下是天嵌TQ2440的打印信息(linux-2.6.30版本),可供参考:

由以上分析,Android的系统,应该是linux的内核启动完成后,再启动必要的进程,最后通过脚步文件启动Android的程序。

参考:Android的init过程详解(一)

 

第二阶段:Android Framework启动

2018-2-7

init 进程(PID=1,用户空间的第一个进程,也是Android系统的第一个进程)进入 main 函数后,主要完成以下四项工作。第一,在根文件系统中创建目录作为挂载点,然后挂载虚拟文件系统;第二, 解析启动脚本文件 init.rc;第三,根据启动脚本 init.rc 的解析结果开启 Android Framework 核心服务进程;第四,监听事件,重启服务。

上面说的init进程(进程名为“/init”,PID=0,根目录下的init可执行文件),,是由android源码(Android-7.1版本)中的/system/core/init/init.cpp文件编译出来的,这个进程名为“/init”的进程会执行根目录下的 init.*.rc 脚步(具体的执行规则,参见:Android的init过程(二):初始化语言(init.rc)解析),这个脚步是负责启动Android framework的(见:Android笔记 - Android启动之Android Framework启动)。

为了学习AIL(Android初始化语言,Android Init Language,这里简称为AIL),读者可以到自己Android手机的根目录寻找init.rc文件,最好下载到本地以便查看,如果有编译好的Android源代码,在<Android源代码根目录>out/target/product/generic/root目录也可找到init.rc文件。

第二步和第三步最重要,这个过程中会启动系统所需功能的各种服务。主要分为本地服务和Android服务,它们都会在ServiceManager中进行注册。

本地服务 
本地服务是指运行在C++层的系统守护进程,一部分本地服务是init进程直接启动的,它们定义在init.rc脚本和init.<hardware>.rc中,如 ueventd、servicemanager、debuggerd、rild、mediaserver等。还有一部分本地服务,是由这些本地服务进一步创建的,如mediaserver服务会启动AudioFlinger, MediaPlayerService, 以及 CameraService 等本地服务。我们可以通过查看init.rc和init.<hardware>.rc文件找出具体有哪些本地服务被init进程直接启动了,这些文件的位置:system/core/rootdir/

Android服务 
Android服务是指运行在Dalvik虚拟机进程中的服务,这些服务的创建过程描述如下:
init进程会执行app_process程序,创建Zygote进程,它是Android系统最重要的进程,后续所有的Android应用程序都是由它fork出来的。 
Zygote进程会先fork出SystemServer进程,SystemServer进程就会启动所有的Android核心服务。例如:Activity Manager、Window Manager、Power Manager等等服务。当所服务启动完毕后,SystemServer会打印出”Making services ready”,然后通过Activity Manager启动Home界面,并发送“ACTION_BOOT_COMPLETED”广播消息。 
SystemServer进程添加的服务都属于SystemServer进程。

Android服务是指运行在Dalvik虚拟机进程中的服务,这些服务的创建过程描述如下:

init进程会执行app_process程序,创建Zygote进程,它是Android系统最重要的进程,所有后续的Android应用程序都是由它fork出来的。

 

第二, 解析启动脚本文件 init.rc;

init 可执行文件的代码(/system/core/init/init.cpp)的main函数中解析“/init.rc”脚步,源码:

int main(int argc, char** argv) {

.......

    Parser& parser = Parser::GetInstance();
    parser.AddSectionParser("service",std::make_unique<ServiceParser>());
    parser.AddSectionParser("on", std::make_unique<ActionParser>());
    parser.AddSectionParser("import", std::make_unique<ImportParser>());
    parser.ParseConfig("/init.rc");
.......
}

解析 init.rc 的工作由函数 Parser 来完成。解析完成后,得到一个 service_list 链表和一个 action_list 链表。其中,service_list 链表用来保存 service 的解析结果,action_list 链表用来保存 action 的解析结果。如下图所示: 

为了让 action 按照一定的顺序触发,需要对 action 在链表中的顺序进行调整,调整后的 action 由 action_queue 链表来保存。

第三,根据启动脚本 init.rc 的解析结果开启 Android Framework 核心服务进程;

通过之前的初始化工作得到 action_queue 链表后,调用 execute_one_command 函数遍历 action_queue 链表,并执行链表中 action 的 command。

在这些启动的核心服务进程中,其中两个最重要的核心服务进程是 zygote 进程和 servicemanager 进程。

zygote 进程是 Android 启动后的第一个虚拟机进程。它主要负责启动 system_server 进程,以及所有的应用程序进程,所以也称为孵化器进程。zygote 进程会启动子进程 system_server,system_server 进程在 nativeInit 函数中启动 Native 系统服务比如 SensorService,在 ServerThread 的 initAndLoop 函数中启动 Java 系统服务比如 ActivityManagerService, PackageManagerService, ContentService 等,并将系统服务注册进 ServiceManager。

servicemanager 进程是 Binder 进程间通信机制的核心之一。它负责管理系统中所有的 Service 组件,提供 Service 组件的注册服务,并且向 Client 组件提供获取 Service 代理对象的服务。

分析 init.rc 文件,发现执行顺序为:

zygote】进程

Android 7.0 版本的 init.rc文件,其中 zygote 在 init.zygote64.rc 中的内容如下:

//android_source\system\core\rootdir\init.zygote64_32.rc
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
    class main
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    writepid /dev/cpuset/foreground/tasks

service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
    class main
    socket zygote_secondary stream 660 root system
    onrestart restart zygote
    writepid /dev/cpuset/foreground/tasks

根据 Android 初始化语言的语法,可以知道 zygote 服务进程的名字是 zygote ,执行程序路径为 /system/bin/app_process64,参数为 -Xzygote /system/bin --zygote --start-system-server。创建一个名字为 zygote 的 socket,这个 socket 用于接收 ActivityManagerService 发送过来的新建应用程序进程的请求。zygote 进程重启时会往 sysfs 中写入命令,同时会重启 media 服务和 netd 服务。

Zygote进程会首先fork出"SystemServer"进程,"SystemServer"进程的全部任务就是将所有的Android核心服务启动起来,这些服务包括:

 

/system/bin/app_process 是 zygote 进程的可执行程序,其源代码位于 frameworks/base/cmds/app_process/app_main.cpp 文件,入口函数是 main。具体启动细节请参考老罗的文章 Android 系统进程 Zygote 启动过程的源代码分析
 

 

 

init.*.rc 脚步依次启动ServiceManager, Zygote, ActivityManagerService 和 PackageManagerService 等系统服务已经启动起来,

其中,android7.1.1版本的ServiceManager对应的启动脚本是/system/etc/init/servicemanager.rc

 

第三阶段:应用程序 Launcher启动

也就是最终会看到的 Android 桌面的启动。

 

 

http://blog.csdn.net/yanshazi/article/details/50287479

 

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/gs344937933/article/details/81217914
今日推荐