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