开机启动概述:
- step 1: 上电开机
长按power键后引导芯片开始从固化在ROM的预设代码处执行,加载引导程序(BootLoader)到RAM. - step 2: BootLoader启动
跳转到BootLoader的入口函数,开始执行BootLoader的代码.
硬件初始化工作(硬件时钟、手机的主板等)
完成初始化uart端口的操作
arch_init
target_init
apps_init
aboot_init
跳转到内核入口函数start_kernel,启动内核. - step 3: kernel 启动
输出Linux版本信息(printk(linux_banner))
设置与体系结构相关的环境(setup_arch())
页表结构初始化(paging_init())
使用"arch/alpha/kernel/entry.S"中的入口点设置系统自陷入口(trap_init())
使用alpha_mv结构和entry.S入口初始化系统IRQ(init_IRQ())
核心进程调度器初始化(包括初始化几个缺省的Bottom-half,sched_init())
时间、定时器初始化(包括读取CMOS时钟、估测主频、初始化定时器中断等,time_init())
提取并分析核心启动参数(从环境变量中读取参数,设置相应标志位等待处理,(parse_options())
控制台初始化(为输出信息而先于PCI初始化,console_init())
剖析器数据结构初始化(prof_buffer和prof_len变量)
核心Cache初始化(描述Cache信息的Cache,kmem_cache_init())
延迟校准(获得时钟jiffies与CPU主频ticks的延迟,calibrate_delay())
内存初始化(设置内存上下界和页表项初始值,mem_init())
创建和设置内部及通用cache(“slab_cache”,kmem_cache_sizes_init())
创建uid taskcount SLAB cache(“uid_cache”,uidcache_init())
创建文件cache(“files_cache”,filescache_init())
创建目录cache(“dentry_cache”,dcache_init())
创建与虚存相关的cache(“vm_area_struct”,“mm_struct”,vma_init())
块设备读写缓冲区初始化(同时创建"buffer_head"cache用户加速访问,buffer_init())
创建页cache(内存页hash表初始化,page_cache_init())
创建信号队列cache(“signal_queue”,signals_init())
初始化内存inode表(inode_init())
创建内存文件描述符表(“filp_cache”,file_table_init())
检查体系结构漏洞(对于alpha,此函数为空,check_bugs())
SMP机器其余CPU(除当前引导CPU)初始化(对于没有配置SMP的内核,此函数为空,smp_init())
启动init过程(创建第一个核心线程,调用init()函数,原执行序列调用cpu_idle() 等待调度, init()) - step4: init 启动
创建文件系统目录并挂载相关的文件系统
初始化log系统
初始化/设置/启动属性相关的资源
完成SELinux相关工作
装载子进程信号处理器
解析init.rc
atcion/service管理
执行action和启动service,包括启动zygote - step5: zygote进程启动
app_process64 启动
AndroidRuntime 启动
art 启动和初始化
zygote init 启动
启动system_server - step 6: system_server启动
初始化和启动framework service
启动常驻进程
启动Home Activity
详细启动过程记录
1.init进程启动 执行init main入口
//system/core/init/main.cpp
int main(int argc, char** argv) {
#if __has_feature(address_sanitizer)
__asan_set_error_report_callback(AsanReportCallback);
#endif
// Boost prio which will be restored later
setpriority(PRIO_PROCESS, 0, -20);
if (!strcmp(basename(argv[0]), "ueventd")) {
return ueventd_main(argc, argv);// init进程创建子进程ueventd,负责设备节点的创建、权限设定等一些列工作
}
if (argc > 1) {
if (!strcmp(argv[1], "subcontext")) {
android::base::InitLogging(argv, &android::base::KernelLogger);
const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();
return SubcontextMain(argc, argv, &function_map);// 初始化日志系统
}
if (!strcmp(argv[1], "selinux_setup")) {
return SetupSelinux(argv);//初始化Linux安全策略
}
if (!strcmp(argv[1], "second_stage")) {
return SecondStageMain(argc, argv);//执行第二阶段启动
}
}
return FirstStageMain(argc, argv);//执行第一阶段启动
}
2.执行第一启动阶段
主要是创建文件系统并执行挂载相关分区
//system/core/init/first_stage_main.cpp
int FirstStageMain(int argc, char** argv) {
CHECKCALL(mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"));// 挂载tmpfs分区
CHECKCALL(mkdir("/dev/pts", 0755));
CHECKCALL(mkdir("/dev/socket", 0755));// 创建dev/socket设备节点
CHECKCALL(mkdir("/dev/dm-user", 0755));
CHECKCALL(mount("devpts", "/dev/pts", "devpts", 0, NULL));// 挂载devpts分区
CHECKCALL(chmod("/proc/cmdline", 0440));
...
CHECKCALL(mount("sysfs", "/sys", "sysfs", 0, NULL));// 挂载sysfs分区
CHECKCALL(mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL));// 挂载selinuxfs分区
CHECKCALL(mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11)));
...
CHECKCALL(mount("tmpfs", "/mnt", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
"mode=0755,uid=0,gid=1000"));
CHECKCALL(mkdir("/mnt/vendor", 0755));
CHECKCALL(mkdir("/mnt/product", 0755));
...
const char* path = "/system/bin/init";
const char* args[] = {path, "selinux_setup", nullptr};
auto fd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC);// 提前创建了kmsg设备节点文件,用于输出log信息
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
close(fd);
execv(path, const_cast<char**>(args));
return 1;
}
3.执行第二启动阶段
主要初始化属性及启动属性服务,读取init.rc启动相关进程
int SecondStageMain(int argc, char** argv) {
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();//用于init进程崩溃时,启动bootloader,让开发者定位问题
}
boot_clock::time_point start_time = boot_clock::now();
trigger_shutdown = [](const std::string& command) { shutdown_state.TriggerShutdown(command); };
SetStdioToDevNull(argv);
InitKernelLogging(argv);
...
PropertyInit();// 初始化属性系统,并从指定文件读取属性
UmountSecondStageRes();
MountExtraFilesystems();
SelinuxSetupKernelLogging();
SelabelInitialize();
SelinuxRestoreContext();
Epoll epoll;//新建epoll
if (auto result = epoll.Open(); !result.ok()) {
PLOG(FATAL) << result.error();
}
InstallSignalFdHandler(&epoll); //设置子进程退出的信号处理
InstallInitNotifier(&epoll); //设置属性更改的通知
StartPropertyService(&property_fd); // 设置其他系统属性并开启系统属性服务
...
InitializeSubcontext();
ActionManager& am = ActionManager::GetInstance();
ServiceList& sm = ServiceList::GetInstance();
LoadBootScripts(