您现在的位置是:首页 >学无止境 >一个非系统工程师所关心的——Android开机流程网站首页学无止境
一个非系统工程师所关心的——Android开机流程
一、Loader层
1. Boot ROM:
上电后,BootRom会被激活,引导芯片代码
开始从预定义的地方(固化在ROM)开始执行,然后加载引导程序到RAM
。
2. Boot Loader引导程序
Android是基于Linux系统的,它没有BIOS程序,取而代之的是BootLoader(系统启动引导程序)。引导程序是厂商加锁和限制的地方,它是针对特定的主板与芯片的。厂商要么使用很受欢迎的引导程序比如redboot
、uboot
、ARMboot
等或者开发自己的引导程序,它不是Android操作系统的一部分。流程图如下:
二、kernel层
Linux内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。
1.init 进程的启动
0号进程:
swapper进程(pid=0):又称idle进程、空闲进程,由系统自动创建, 运行在内核态。
系统初始化过程Kernel由无到有开创的第一个进程, 也是唯一一个没有通过fork或者kernel_thread产生的进程。
swapper进程用于初始化进程管理、内存管理,加载Display,Camera Driver,Binder Driver等相关工作。
1号进程(就是init进程)
init进程(pid=1):由0号进程通过kernel_thread创建,在内核空间完成初始化后, 加载init程序, 并最终运行在用户空间,init进程是所有用户进程的鼻祖,他的作用是:
(1)是挂载tmpfs, devpts, proc, sysfs文件系统
。
(2)是运行init.rc脚本,init将会解析init.rc,并且执行init.rc中的命令。
(3)当一些关键进程死亡时,重启该进程;
(4)提供Android系统的属性服务
2号进程
kthreadd进程(pid=2):由0号进程通过kernel_thread创建,是Linux系统的内核进程,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等内核守护进程。
kthreadd运行在内核空间, 负责所有内核线程的调度和管理 , kthreadd进程是所有内核进程的鼻祖
。
三、init进程启动了zygote和serviceManager
1.Zygote启动
我们关注的是:Linux内核启动后,会加载system/core/init/init.rc文件,启动init进程,init进程会fork Zygote进程,Zygote作为孵化器进程,它的main函数会创建好自己的环境准备孵化子进程,并开始等待孵化请求。
init.rc文件内容很多,我们就贴一点出来
chown system system /dev/stune/tasks
chmod 0664 /dev/stune/tasks
mkdir /dev/binderfs
mkdir /mnt/user/0/emulated/0 0755 root root
start servicemanager //重点2 servicemanager启动
start hwservicemanager
start vndservicemanager
import /system/etc/init/hw/init.${ro.zygote}.rc
trigger zygote-start
on zygote-start && property:ro.crypto.state=unencrypted
wait_for_prop odsign.verification.done 1
# A/B update verifier that marks a successful boot.
exec_start update_verifier_nonencrypted
start statsd
start netd
start zygote
start zygote_secondary
可见init启动了zygote、servicemanager等等。
那么我们先看zygote是怎么启动的,后面再看serviceManager。我们来看一下init.zygote64.rc文件
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
可见启动了app_process程序,app_process的源码在frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, const char* const argv[])
{
// These are global variables in ProcessState.cpp
mArgC = argc;
mArgV = argv;
mArgLen = 0;
for (int i=0; i<argc; i++) {
mArgLen += strlen(argv[i]) + 1;
}
mArgLen--;
AppRuntime runtime;
const char* argv0 = argv[0];
// Process command line arguments
// ignore argv[0]
argc--;
argv++;
// Everything up to '--' or first non '-' arg goes to the vm
int i = runtime.addVmArguments(argc, argv);
// Parse runtime arguments. Stop at first unrecognized option.
bool zygote = false;
bool startSystemServer = false;
bool application = false;
const char* parentDir = NULL;
const char* niceName = NULL;
const char* className = NULL;
while (i < argc) {
const char* arg = argv[i++];
if (!parentDir) {
parentDir = arg;
} else if (strcmp(arg, "--zygote") == 0) {
zygote = true;//zygote进程
niceName = "zygote";
} 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 = arg + 12;
} else {
className = arg;
break;
}
}
if (niceName && *niceName) {
setArgv0(argv0, niceName);
set_process_name(niceName);
}
runtime.mParentDir = parentDir;
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer ? "start-system-server" : "");//在这里通过runtime启动ZygoteInit从此由内核C层进入了我们的应用层。
} else if (className) {
// Remainder of args get passed to startup class main()
runtime.mClassName = className;
runtime.mArgC = argc - i;
runtime.mArgV = argv + i;
runtime.start("com.android.internal.os.RuntimeInit",
application ? "application" : "tool");
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.
");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
return 10;
}
}
我们看看/java/com/android/internal/os/ZygoteInit.java 类都做了些什么
static void preload(TimingsTraceLog bootTimingsTraceLog) {
Log.d(TAG, "begin preload");
beginPreload();
preloadClasses();//预加载类,其中就包括我们熟悉的系统API
cacheNonBootClasspathClassLoaders();加载无法放入Boot classpath的文件
preloadResources();加载drawables、colors
nativePreloadAppProcessHALs();加载hal 硬件
maybePreloadGraphicsDriver();调用OpenGL/Vulkan加载图形驱动程序
preloadSharedLibraries();//加载共享库
preloadTextResources();初始化TextView ,对,你没看错
WebViewFactory.prepareWebViewInZygote();//初始化webview
endPreload();// 取消软引用保护
warmUpJcaProviders(); 初始化JCA安全相关的参数,比如AndroidKeyStoreProvider安装
sPreloadComplete = true;
}
for系统服务:
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
StructCapUserHeader header = new StructCapUserHeader(
OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
StructCapUserData[] data;
try {
data = Os.capget(header);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to capget()", ex);
}
capabilities &= Integer.toUnsignedLong(data[0].effective) |
(Integer.toUnsignedLong(data[1].effective) << 32);
String[] args = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
+ "1024,1032,1065,3001,3002,3003,3005,3006,3007,3009,3010,3011,3012",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
ZygoteArguments parsedArgs;
int pid;
try {
ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args);
try {
parsedArgs = ZygoteArguments.getInstance(commandBuffer);
} catch (EOFException e) {
throw new AssertionError("Unexpected argument error for forking system server", e);
}
commandBuffer.close();
Zygote.applyDebuggerSystemProperty(parsedArgs);
Zygote.applyInvokeWithSystemProperty(parsedArgs);
if (Zygote.nativeSupportsMemoryTagging()) {
String mode = SystemProperties.get("arm64.memtag.process.system_server", "");
if (mode.isEmpty()) {
/* The system server has ASYNC MTE by default, in order to allow
* system services to specify their own MTE level later, as you
* can't re-enable MTE once it's disabled. */
mode = SystemProperties.get("persist.arm64.memtag.default", "async");
}
if (mode.equals("async")) {
parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_ASYNC;
} else if (mode.equals("sync")) {
parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_SYNC;
} else if (!mode.equals("off")) {
/* When we have an invalid memory tag level, keep the current level. */
parsedArgs.mRuntimeFlags |= Zygote.nativeCurrentTaggingLevel();
Slog.e(TAG, "Unknown memory tag level for the system server: "" + mode + """);
}
} else if (Zygote.nativeSupportsTaggedPointers()) {
/* Enable pointer tagging in the system server. Hardware support for this is present
* in all ARMv8 CPUs. */
parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_TBI;
}
/* Enable gwp-asan on the system server with a small probability. This is the same
* policy as applied to native processes and system apps. */
parsedArgs.mRuntimeFlags |= Zygote.GWP_ASAN_LEVEL_LOTTERY;
if (shouldProfileSystemServer()) {
parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}
/* Request to fork the system server process */
pid = Zygote.forkSystemServer( //调用zygote fork 系统服务
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
所以最终调用 java/com/android/internal/os/Zygote.java 的 forkSystemServer,我们看一下源码
static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
ZygoteHooks.preFork();
int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits,
permittedCapabilities, effectiveCapabilities);
// Set the Java Language thread priority to the default value for new apps.
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
ZygoteHooks.postForkCommon();
return pid;
}
所以systemServer就这么启动了。
好了,具体的细节我们就跟踪到这里,有兴趣的可以看源码,源码有详细的过程。
2.servicemanager启动
我们看到 init 也启动了/system/bin/servicemanager程序,servicemanager程序的源码在android/frameworks/native/cmds/servicemanager/main.cpp
int main(int argc, char** argv) {
android::base::InitLogging(argv, android::base::KernelLogger);
if (argc > 2) {
LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
}
const char* driver = argc == 2 ? argv[1] : "/dev/binder";
LOG(INFO) << "Starting sm instance on " << driver;
sp<ProcessState> ps = ProcessState::initWithDriver(driver);//驱动层创建binder_proc
ps->setThreadPoolMaxThreadCount(0);
ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);
//创建ServiceManager
sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>());
//添加服务
if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
LOG(ERROR) << "Could not self register servicemanager";
}
IPCThreadState::self()->setTheContextObject(manager);
if (!ps->becomeContextManager()) {//注册成为binder服务的大管家
LOG(FATAL) << "Could not become context manager";
}
//开启looper 消息循环 监听 BinderCallback
sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);
BinderCallback::setupTo(looper); //处理Binder请求
ClientCallbackCallback::setupTo(looper, manager);//定时通知client变化
#ifndef VENDORSERVICEMANAGER
if (!SetProperty("servicemanager.ready", "true")) {
LOG(ERROR) << "Failed to set servicemanager ready property";
}
#endif
while(true) {
looper->pollAll(-1);
}
// should not be reached
return EXIT_FAILURE;
}
。。。等待继续