Android系统启动流程
本文链接:https://blog.csdn.net/feather_wch/article/details/132518105
有道云脑图:https://note.youdao.com/s/GZ9d8vzO
1、整体流程
- Boot Room
- BootLoader
- idle
- kthread
- init
- init
- ServiceManager
- zygote
- zygote
- SystemServer
- app
一、init
1、kernel/common/init/main.c
kernel_init();
->try_to_run_init_process("/bin/init");
->run_init_process(filename)
->kernel_execve(filename, xxx, xxx);
->// 会执行init
2、andorid.mk->android.bp编译
// init/android.bp
cc_binary {
name: "init_second_stage",
stem: "init",
static_libs: ["libinit"],
srcs: ["main.cpp"], // main.cpp
// ...
}
3、init是用户空间鼻祖
- 属于C、C++ Framework
1.1 启动源码
FirstStageMain()
->挂载文件系统
->重定向输入输出
SetupSelinux()
->初始化Selinux
SecondStageMain()
->初始化属性
->设置Selinux
->监听子进程终止信号
->epoll_ctl 注册监听SIGCHILD 避免僵尸进程
->启动属性服务,将sokcet,注册到epoll中
->匹配命令和函数
->解析init.rc
->构造解析器,对应于rc文件里面的service、on、import
->parser.ParseConfig:解析rc文件
->解析Dir
->解析File
->按照二进制格式,解析:servicemanager、zygote
-> 循环执行脚本,epoll循环等待
-> 执行脚本
// frameworks/core/core/init/main.cpp
int main(int argc, char** argv) {
// 会反复进入
// 2、第二次进来,根据参数执行
if (argc > 1) {
if (!strcmp(argv[1], "subcontext")) {
const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();
// 5、内部while+poll,第四阶段
return SubcontextMain(argc, argv, &function_map);
}
// 3、selinux:第二阶段
if (!strcmp(argv[1], "selinux_setup")) {
return SetupSelinux(argv);
}
// 4、第三阶段
if (!strcmp(argv[1], "second_stage")) {
return SecondStageMain(argc, argv);
}
}
// 1、首次进来:第一阶段
return FirstStageMain(argc, argv);
}
// 第一阶段:
int FirstStageMain(int argc, char** argv) {
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
}
CHECKCALL(clearenv());
CHECKCALL(setenv("PATH", _PATH_DEFPATH, 1));
// 1、挂载文件系统
CHECKCALL(mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"));
CHECKCALL(mount("devpts", "/dev/pts", "devpts", 0, NULL));
CHECKCALL(mount("sysfs", "/sys", "sysfs", 0, NULL));
CHECKCALL(mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL));
CHECKCALL(mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8)));
CHECKCALL(mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9)));
// null也是作为管道文件进行处理
CHECKCALL(mknod("/dev/null", S_IFCHR | 0666, makedev(1, 3)));
CHECKCALL(mkdir("/mnt/vendor", 0755));
CHECKCALL(mkdir("/mnt/product", 0755));
// 2、重定向输入输出:stdio重定向Dev Null,作为管道文件,输入输出
SetStdioToDevNull(argv);
// 日志输出初始化
InitKernelLogging(argv);
// 3、设置selinux安全策略:重新进入main.cpp
const char* path = "/system/bin/init";
const char* args[] = {path, "selinux_setup", nullptr};
execv(path, const_cast<char**>(args)); // 执行
return 1;
}
// Selinux:设置SeLinux安全策略,Android最小权限原则,selinux控制
int SetupSelinux(char** argv) {
// 设置selinux
SelinuxSetupKernelLogging();
// selinux初始化
SelinuxInitialize();
// 重新进入第二阶段
const char* path = "/system/bin/init";
const char* args[] = {path, "second_stage", nullptr};
execv(path, const_cast<char**>(args));
return 1;
}
// frameworks/core/core/init.coo
int SecondStageMain(int argc, char** argv) {
// Set init and its forked children's oom_adj.
if (auto result = WriteFile("/proc/1/oom_score_adj", StringPrintf("%d", DEFAULT_OOM_SCORE_ADJUST));
!result.ok()) {
LOG(ERROR) << "Unable to write " << DEFAULT_OOM_SCORE_ADJUST
<< " to /proc/1/oom_score_adj: " << result.error();
}
// 1. 初始化属性:加载属性
PropertyInit();
// Mount extra filesystems required during second stage init
MountExtraFilesystems();
// 2. Selinux相关
SelinuxSetupKernelLogging();
SelabelInitialize();
SelinuxRestoreContext();
Epoll epoll; // ===============================================================================> epoll
if (auto result = epoll.Open(); !result.ok()) {
PLOG(FATAL) << result.error();
}
// 3. 监听子进程中止信号:避免僵尸进程 ==============================================================> 僵尸进程
InstallSignalFdHandler(&epoll);
InstallInitNotifier(&epoll);
// 4. 启动属性服务
StartPropertyService(&property_fd);
SetUsbController();
// 5. 匹配命令和函数的关系:mount等命令都对应于函数
const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();
Action::set_function_map(&function_map);
// 6. 解析 init.rc
LoadBootScripts(am, sm);
// 7. while循环解析脚本:启动zygote、执行重启
while (true) {
// 解析start等命令
am.ExecuteOneCommand();
// epoll_wait循环等待 ===================================================================> Handler中Looper.loop
auto pending_functions = epoll.Wait(epoll_timeout);
}
return 0;
}
// >>>>>>>>>>>>>>>>>>>>>>>>>>
//在linux当中,父进程是通过捕捉SIGCHLD信号来得知子进程运行结束的情况,
//SIGCHLD信号会在子进程终止的时候发出
//函数的作用就是,接收到SIGCHLD信号时触发HandleSignalFd进行信号处理
// 这样可以在当子进程发出信号后能够及时的将它销毁,避免僵尸进程的存在
static void InstallSignalFdHandler(Epoll* epoll) {
const struct sigaction act { .sa_handler = SIG_DFL, .sa_flags = SA_NOCLDSTOP };
sigaction(SIGCHLD, &act, nullptr);
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD); //SIGCHLD
signal_fd = signalfd(-1, &mask, SFD_CLOEXEC);
// 注册,epoll注册handler。 ===========================> epoll_ctl EPOLL_CTL_ADD
if (auto result = epoll->RegisterHandler(signal_fd, HandleSignalFd); !result.ok()) {
LOG(FATAL) << result.error();
}
}
// 注册,epoll注册handler。 ===========================> epoll_ctl EPOLL_CTL_ADD
Result<void> Epoll::RegisterHandler(int fd, std::function<void()> handler, uint32_t events) {
epoll_event ev;
ev.events = events;
ev.data.ptr = reinterpret_cast<void*>(&it->second);
if (epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &ev) == -1) {
epoll_handlers_.erase(fd);
return result;
}
return {};
}
// >>>>>>>>>>>>>>>>>>> 启动属性服务,注册到epoll中
void StartPropertyService(int* epoll_socket) {
InitPropertySet("ro.property_service.version", "2");
int sockets[2];
if (socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sockets) != 0) {
PLOG(FATAL) << "Failed to socketpair() between property_service and init";
}
*epoll_socket = from_init_socket = sockets[0];
init_socket = sockets[1];
StartSendingMessages();
if (auto result = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, false, 0666, 0, 0, {});
result.ok()) {
property_set_fd = *result;
}
listen(property_set_fd, 8);
auto new_thread = std::thread{PropertyServiceThread};
property_service_thread.swap(new_thread);
}
init.rc解析
// 解析init.rc
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
// 1、创建对应解析器 service、on、import
Parser parser = CreateParser(action_manager, service_list);
// 2、解析init.rc init.rc里面有zygote等等
std::string bootscript = GetProperty("ro.boot.init_rc", "");
if (bootscript.empty()) {
parser.ParseConfig("/system/etc/init/hw/init.rc");
if (!parser.ParseConfig("/system/etc/init")) {
late_import_paths.emplace_back("/system/etc/init");
}
parser.ParseConfig("/system_ext/etc/init");
if (!parser.ParseConfig("/product/etc/init")) {
late_import_paths.emplace_back("/product/etc/init");
}
if (!parser.ParseConfig("/odm/etc/init")) {
late_import_paths.emplace_back("/odm/etc/init");
}
if (!parser.ParseConfig("/vendor/etc/init")) {
late_import_paths.emplace_back("/vendor/etc/init");
}
} else {
parser.ParseConfig(bootscript);
}
}
// 根据rc文件的内容,创建对应解析器
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {
Parser parser;
parser.AddSectionParser("service", std::make_unique<ServiceParser>(&service_list, GetSubcontext(), std::nullopt));
parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager, GetSubcontext()));
parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));
return parser;
}
// frameworks/core/core/init/parse.cpp
// 解析
bool Parser::ParseConfig(const std::string& path) {
if (is_dir(path.c_str())) {
return ParseConfigDir(path); // 目录 -> ParseConfigFile
}
return ParseConfigFile(path); // 文件
}
bool Parser::ParseConfigFile(const std::string& path) {
// 解析数据
ParseData(path, &config_contents.value());
return true;
}
// 根据二进制格式要求,解析数据
void Parser::ParseData(const std::string& filename, std::string* data) {
for (;;) {
switch (next_token(&state)) {
case T_EOF:
// ...
return;
case T_NEWLINE: {
// ...
break;
}
case T_TEXT:
args.emplace_back(state.text);
break;
}
}
}
1.2 init.rc文件
import /system/etc/init/hw/init.${ro.zygote}.rc
on init
# Mount binderfs
mkdir /dev/binderfs
mount binder binder /dev/binderfs stats=global
chmod 0755 /dev/binderfs
symlink /dev/binderfs/binder /dev/binder
symlink /dev/binderfs/hwbinder /dev/hwbinder
symlink /dev/binderfs/vndbinder /dev/vndbinder
# Start essential services.
start servicemanager
start hwservicemanager
start vndservicemanager
on late-init
# Now we can start zygote for devices with file based encryption
trigger 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 statsd
start netd
start zygote
start zygote_secondary
二、ServiceManager
ServiceManager启动流程:见Binder部分。
main()
->1.初始化Binder驱动,加载"/dev/binder"
->2.实例化ServiceManager,并将自己作为第一个服务,进行添加注册
->3.将自己设置为IPCThreadState的contextobject,也就是设置服务端的BBinder对象
->4.利用Looper,也就是底层epoll处理事务,设置BinderCallback监听(epoll_ctl),无限等待
->5.while() // Binder驱动遇到事件,会回调handleEvent
三、Zygote
3.1 rc解析
// init.zygote64.rc
# 启动一个服务
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
socket usap_pool_primary stream 660 root system
# zygote被关闭就会重启Android操作系统
onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
// frameworks/base/cmds/app_process/Android.bp
cc_binary {
name: "app_process",
srcs: ["app_main.cpp"] // 指明代码为app_main.cpp
}
3.2 启动:app_main.cpp
AppRuntime
class AppRuntime : public AndroidRuntime
{
public:
AppRuntime(char* argBlockStart, const size_t argBlockLength): AndroidRuntime(argBlockStart, argBlockLength), mClass(NULL){}
void setClassNameAndArgs(const String8& className, int argc, char * const *argv) {
mClassName = className;
for (int i = 0; i < argc; ++i) {
mArgs.add(String8(argv[i]));
}
}
virtual void onVmCreated(JNIEnv* env)
{
if (mClassName.isEmpty()) {
return; // Zygote. Nothing to do here.
}
char* slashClassName = toSlashClassName(mClassName.string());
mClass = env->FindClass(slashClassName);
if (mClass == NULL) {
ALOGE("ERROR: could not find class '%s'\n", mClassName.string());
}
free(slashClassName);
mClass = reinterpret_cast<jclass>(env->NewGlobalRef(mClass));
}
virtual void onStarted()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
AndroidRuntime* ar = AndroidRuntime::getRuntime();
ar->callMain(mClassName, mClass, mArgs);
IPCThreadState::self()->stopProcess();
hardware::IPCThreadState::self()->stopProcess();
}
// nativeZygoteInit调用时,被JNI中转到这里。
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self(); // 1、初始化ProcessState(初始化Binder驱动)
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool(); // 2、创建Binder线程池,底层一路到IPCThreadState::self()->joinThreadPool();
}
virtual void onExit(int code)
{
if (mClassName.isEmpty()) {
// if zygote
IPCThreadState::self()->stopProcess();
hardware::IPCThreadState::self()->stopProcess();
}
AndroidRuntime::onExit(code);
}
String8 mClassName;
Vector<String8> mArgs;
jclass mClass;
};
main
1、app_main.cpp 启动Zygote或者正常app流程 ->目录frameworks\base\cmds\app_process\
// 核心:根据init.zygote64.rc里面配置的参数,--zygote和--start-system-server,启动zygote,systemserver作为参数传入,以后启动
int main(int argc, char* const argv[])
{
/**========================
* 1、根据rc配置,解析出需要启动zygote,并且在zygote启动后,
*========================*/
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
// 解析传入的参数 -Xzygote /system/bin --zygote --start-system-server
int i;
for (i = 0; i < argc; i++) {
// 参数解析
runtime.addOption(strdup(argv[i]));
}
// 判断是zygote还是app
bool zygote = false;
bool startSystemServer = false; // 用于存入参数
bool application = false; // app
String8 niceName;
String8 className;
++i; // Skip unused "parent dir" argument.
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
} else {
--i;
break;
}
}
Vector<String8> args;
if (!className.isEmpty()) {
// 非zygote模式,存入application启动相关参数
args.add(application ? String8("application") : String8("tool"));
runtime.setClassNameAndArgs(className, argc - i, argv + i);
} else {
// zygote模式,将systemserver和其他剩余参数,都一次性放入
if (startSystemServer) {
args.add(String8("start-system-server"));
}
String8 abiFlag("--abi-list=");
abiFlag.append(prop);
args.add(abiFlag);
// In zygote mode, pass all remaining arguments to the zygote
// main() method.
for (; i < argc; ++i) {
args.add(String8(argv[i]));
}
}
/**===============================================
* 2、启动zygote(systemserver等内容作为参数传入)
*====================