简单流程
- 启动电源及系统启动
当电源按下时引导芯片代码开始从预定义的ROM中开始执行。加载引导程序Bootloader至RAM
- 引导进程Bootloader
是系统启动前的一个小程序,主要用于将系统的OS拉起来并运行
- Linux Kernel进程
内核启动时,设置缓存、被保护存储、计划列表、加载驱动。内核完成系统设置后,在系统文件中寻找init文件,然后启动root进程或系统的第一个进程
- init进程(native)
解析init文件孵化出zygote进程(JVM第一个进程,所有进程的父进程)
- Zygote进程(framework)
创建虚拟机JVM并为其注册JNI方法,创建服务端socket,启动SystemServer进程
- SystemServer进程
用于启动各种服务,AMS,PMS,WWS等
- Launcher
AMS启动
具体流程分析
- Bootloader引导进程
-
Linux Kernel进程:加载各种驱动和数据结构,寻找系统文件中的init.rc文件,加载用户级别的第一个进程.
加载init.rc配置文件
int main(int argc, char** argv) {
if (!strcmp(basename(argv[0]), "ueventd")) {
return ueventd_main(argc, argv);
}
if (!strcmp(basename(argv[0]), "watchdogd")) {
return watchdogd_main(argc, argv);
}
if (argc > 1 && !strcmp(argv[1], "subcontext")) {
InitKernelLogging(argv);
const BuiltinFunctionMap function_map;
return SubcontextMain(argc, argv, &function_map);
}
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
}
bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);
if (is_first_stage) {
boot_clock::time_point start_time = boot_clock::now();
// Clear the umask.
umask(0);
clearenv();
setenv("PATH", _PATH_DEFPATH, 1);
// Get the basic filesystem setup we need put together in the initramdisk
// on / and then we'll let the rc file figure out the rest.
// 创建文件夹,挂载
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
mkdir("/dev/pts", 0755);
mkdir("/dev/socket", 0755);
mount("devpts", "/dev/pts", "devpts", 0, NULL);
#define MAKE_STR(x) __STRING(x)
mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
// Don't expose the raw commandline to unprivileged processes.
chmod("/proc/cmdline", 0440);
gid_t groups[] = {
AID_READPROC };
setgroups(arraysize(groups), groups);
mount("sysfs", "/sys", "sysfs", 0, NULL);
mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
if constexpr (WORLD_WRITABLE_KMSG) {
mknod("/dev/kmsg_debug", S_IFCHR | 0622, makedev(1, 11));
}
mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));
// Mount staging areas for devices managed by vold
// See storage config details at http://source.android.com/devices/storage/
mount("tmpfs", "/mnt", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
"mode=0755,uid=0,gid=1000");
// /mnt/vendor is used to mount vendor-specific partitions that can not be
// part of the vendor partition, e.g. because they are mounted read-write.
mkdir("/mnt/vendor", 0755);
// Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually
// talk to the outside world...
// 打开日志
InitKernelLogging(argv);
...
}
...
// 加载init.rc文件
LoadBootScripts(am, sm);
...
}
- init.rc配置文件会进行很多的配置,创建很多的文件夹及文件,之后初始化Android驱动器,继而启动zygote进程
# It is recommended to put unnecessary data/ initialization from post-fs-data
# to start-zygote in device's init.rc to unblock zygote start.
on zygote-start && property:ro.crypto.state=unencrypted
# A/B update verifier that marks a successful boot.
exec_start update_verifier_nonencrypted
start netd
start zygote
start zygote_secondary
on zygote-start && property:ro.crypto.state=unsupported
# A/B update verifier that marks a successful boot.
exec_start update_verifier_nonencrypted
start netd
start zygote
start zygote_secondary
on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file
# A/B update verifier that marks a successful boot.
exec_start update_verifier_nonencrypted
start netd
start zygote
start zygote_secondary
- zygote进程会执行app_process可执行文件,在该文件中先添加Android的运行环境。在Android运行中调用了ZygoteInit.java,这就实现了从C++跳转到java代码
int main(int argc, const char* const argv[])
{
...
// Android运行时环境
AppRuntime runtime;
...
// Next arg is startup classname or "--zygote"
if (i < argc
版权声明:本文为qq_34787560原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。