文章目录
- 2.1 init 进程启动过程
- 2.1.1 引入 init 进程
- 2.1.2 init 进程的入口函数
- 2.1.3 解析 init.rc
- 2.1.4 解析 Service
- 2.1.5 init 启动 zygote
- 2.1.6 属性服务
- 2.1.7 init 进程启动总结
- 2.2 Zygote 进程启动过程
- 2.2.1 Zygote概述
- 2.2.2 Zygote 启动脚本
- 2.2.3 Zygote进程启动过程介绍
- 2.2.4 Zygote进程启动总结
- 2.3 SystemServer 处理过程
- 2.3.1 Zygote 处理 SystemServer 进程
- 2.3.2 解析 SystemServer 进程
- 2.3.3 SystemServer 进程总结
- 2.4 Launcher 启动过程
- 2.4.1 Launcher 概述
- 2.4.3 Launcher 中应用图标显示过程
- 2.5 Android系统启动流程
2.1 init 进程启动过程
- init 进程是 Android 系统中用户空间的第一个进程,进程号为 1,主要创建 Zygote(孵化器)和系统服务,文件位于 system/core/init 中。
2.1.1 引入 init 进程
- Android 系统启动流程
启动步骤 |
简介 |
启动电源以及系统启动 |
引导芯片代码从预定义的地方(固话ROM)开始执行,加载引导程序BootLoader到RAM中,执行 |
引到程序BootLoader |
把系统OS拉起来运行 |
Linux内核启动 |
设置缓存、被保护存储器、计划列表、加载驱动。在内核完成系统设置后,他首先在系统文件中寻找init.rc 文件,启动 init 进程 |
init进程启动 |
初始化和启动属性服务,启动 Zygote进程 |
2.1.2 init 进程的入口函数
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();
umask(0);
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
mkdir("/dev/pts", 0755);
mkdir("/dev/socket", 0755);
mount("devpts", "/dev/pts", "devpts", 0, NULL);
......
InitKernelLogging(argv);
}
property_init();
epoll_fd = epoll_create1(EPOLL_CLOEXEC);
if (epoll_fd == -1) {
PLOG(FATAL) << "epoll_create1 failed";
}
sigchld_handler_init();
property_load_boot_defaults();
export_oem_lock_status();
start_property_service();
set_usb_controller();
if (bootscript.empty()) {
parser.ParseConfig("/init.rc");
parser.set_is_system_etc_init_loaded(
parser.ParseConfig("/system/etc/init"));
parser.set_is_vendor_etc_init_loaded(
parser.ParseConfig("/vendor/etc/init"));
parser.set_is_odm_etc_init_loaded(parser.ParseConfig("/odm/etc/init"));
} else {
parser.ParseConfig(bootscript);
parser.set_is_system_etc_init_loaded(true);
parser.set_is_vendor_etc_init_loaded(true);
parser.set_is_odm_etc_init_loaded(true);
}
...
while (true) {
int epoll_timeout_ms = -1
if (!(waiting_for_prop || Service::is_exec_service_running())) {
am.ExecuteOneCommand();
}
if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) {
restart_processes();
}
}
2.1.3 解析 init.rc
- 非常重要配置文件,由 Android 初始语言编写脚步(Action、Command、Service、Option、Import)
- 分析 Zygote 启动脚本
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
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
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
2.1.4 解析 Service
- init.rc 中 Action 和 Service 都有相应的类来解析,分别为 ActionParse、ServiceParse
- 看 ServiceParse,在 system/core/init/service.cpp
Result<Success> ServiceParser::ParseSection(std::vector<std::string>&& args,
const std::string& filename, int line) {
if (args.size() < 3) {
return Error() << "services must have a name and a program";
}
const std::string& name = args[1];
if (!IsValidName(name)) {
return Error() << "invalid service name '" << name << "'";
}
std::vector<std::string> str_args(args.begin() + 2, args.end());
service_ = std::make_unique<Service>(name, restart_action_subcontext, str_args);
return Success();
}
2.1.5 init 启动 zygote
- 在 system/core/init/builtins.cpp# do_class_start 遍历 Service 链表,找到 classname 为 main 的 zygote,执行 system/core/init/service.cpp#StartIfNotDisabled -> 调用 system/core/init/service.cpp#Start()->froameworks/base/cmds/app_process/app_process/app_main.cpp#main() 函数中,通过 runtime.start() 启动 zygote。
2.1.6 属性服务
- 类似于 Window 的注册表管理器(键值对存储记录用户、软件信息)
- init 进程启动时,会启动属性服务,为其分配内存,存储属性。
void property_init() {
if (__system_property_area_init()) {
LOG(ERROR) << "Failed to initialize property area";
exit(1);
}
}
void start_property_service() {
property_set("ro.property_service.version", "2");
property_set_fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
0666, 0, 0, NULL);
if (property_set_fd == -1) {
PLOG(ERROR) << "start_property_service socket creation failed";
exit(1);
}
listen(property_set_fd, 8);
register_epoll_handler(property_set_fd, handle_property_set_fd);
}
static void handle_property_set_fd() {
.....
switch (cmd) {
case PROP_MSG_SETPROP: {
char prop_name[PROP_NAME_MAX];
char prop_value[PROP_VALUE_MAX];
if (!socket.RecvChars(prop_name, PROP_NAME_MAX, &timeout_ms) ||
!socket.RecvChars(prop_value, PROP_VALUE_MAX, &timeout_ms)) {
PLOG(ERROR) << "sys_prop(PROP_MSG_SETPROP): error while reading name/value from the socket";
return;
}
prop_name[PROP_NAME_MAX-1] = 0;
prop_value[PROP_VALUE_MAX-1] = 0;
handle_property_set(socket, prop_value, prop_value, true);
break;
}
}
static void handle_property_set(SocketConnection& socket,
const std::string& name,
const std::string& value,
bool legacy_protocol) {
const char* cmd_name = legacy_protocol ? "PROP_MSG_SETPROP" : "PROP_MSG_SETPROP2";
if (!is_legal_property_name(name)) {
LOG(ERROR) << "sys_prop(" << cmd_name << "): illegal property name \"" << name << "\"";
socket.SendUint32(PROP_ERROR_INVALID_NAME);
return;
}
struct ucred cr = socket.cred();
char* source_ctx = nullptr;
getpeercon(socket.socket(), &source_ctx);
if (android::base::StartsWith(name, "ctl.")) {
if (check_control_mac_perms(value.c_str(), source_ctx, &cr)) {
handle_control_message(name.c_str() + 4, value.c_str());
if (!legacy_protocol) {
socket.SendUint32(PROP_SUCCESS);
}
} else {
LOG(ERROR) << "sys_prop(" << cmd_name << "): Unable to " << (name.c_str() + 4)
<< " service ctl [" << value << "]"
<< " uid:" << cr.uid
<< " gid:" << cr.gid
<< " pid:" << cr.pid;
if (!legacy_protocol) {
socket.SendUint32(PROP_ERROR_HANDLE_CONTROL_MESSAGE);
}
}
} else {
if (check_mac_perms(name, source_ctx, &cr)) {
uint32_t result = property_set(name, value);
if (!legacy_protocol) {
socket.SendUint32(result);
}
} else {
LOG(ERROR) << "sys_prop(" << cmd_name << "): permission denied uid:" << cr.uid << " name:" << name;
if (!legacy_protocol) {
socket.SendUint32(PROP_ERROR_PERMISSION_DENIED);
}
}
}
freecon(source_ctx);
}
2.1.7 init 进程启动总结
- 创建和挂载启动所需的文件目录(文件)
- 初始化和启动属性服务(属性服务)
- 解析 init.rc 配置文件 并且启动 zygote(zygote)
2.2 Zygote 进程启动过程
2.2.1 Zygote概述
- Zygote进程:DVM和ART、应用程序进程以及运行系统的服务 SystemServe,称为孵化器,通过 fork 进程形式
- Zygote进程名称叫做 “app_process”,在 Android.mk 中定义,Linux系统下的 pctrl 会调用 app_pocess,将名称换成 zygote
2.2.2 Zygote 启动脚本
- Android 初始化语言
- import/init.${ro.zygote}.rc:1.init.zygote32.rc;2.init.zygote32_64.rc;3.init.zygote64.rc;4.init.zygote64_32.rc
- 在 sysytem/core/rootdir 中
2.2.3 Zygote进程启动过程介绍
int main(int argc, char* const argv[]){
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;
}
}
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
}
}
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
public static void main(String argv[]) {
zygoteServer.registerServerSocket(socketName);
if (startSystemServer) {
startSystemServer(abiList, socketName, zygoteServer);
}
zygoteServer.runSelectLoop(abiList);
}
void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
fds.add(mServerSocket.getFileDescriptor());
while (true) {
}
}
- ZygoteInit main 方法
1.创建一个 Server端Socket
2.预加载类和资源
3.启动SystemServer
4.等待AMS请求创建新的应用程序进程
2.2.4 Zygote进程启动总结
- 创建 AppRuntime 并调用 start,启动 Zygote 方法
- 创建 java虚拟机,注册 JNI方法
- JNI调用 ZygoteInit 的main函数进去 Zygote 的 java 层中
- 通过 registerZygoteSocket 创建服务端 socket,并通过 runSelectLoop 等待 AMS请求 来创建新的应用进程。
- 启动 SystemServer 进程
2.3 SystemServer 处理过程
2.3.1 Zygote 处理 SystemServer 进程
private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
throws Zygote.MethodAndArgsCaller, RuntimeException {
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
handleSystemServerProcess(parsedArgs);
}
}
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws Zygote.MethodAndArgsCaller {
ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
public static final void zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
ZygoteInit.nativeZygoteInit();
RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
2.3.2 解析 SystemServer 进程
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
Looper.prepareMainLooper()
System.loadLibrary("android_servers");
createSystemContext();
mSystemServiceManager = new SystemServiceManager(mSystemContext);
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
}
}
2.3.3 SystemServer 进程总结
- 启动 Binder 线程池,与其他进程通信
- 创建 SystemServiceManager,对系统服务生命周期管理
- 启动各种服务
2.4 Launcher 启动过程
2.4.1 Launcher 概述
- 最后一步启动一个应用程序来显示系统安装的应用程序,Launcher。
- 请求 PMS 返回系统已经安装的应用程序信息,封装成快捷图标列表展示在屏幕上
- 作用
1.作为Android系统启动器,用于启动应用程序
2.作为Android系统桌面,显示和管理应用程序的快捷图标或其他桌面组件。
SystemServer AMS ActStackSupervisor ActivityStack systemReady 调用 AMS中方法,launcher 入口 resumeFocusedStack resumeToActivity resumeToActivityInnerLocked resumeHomeStackTask startHomeActivityLocked mFactoryTest非工 厂模式、低级、 高级 SystemServer AMS ActStackSupervisor ActivityStack
2.4.3 Launcher 中应用图标显示过程
protected void onCreate(Bundle savedInstanceState) {
LauncherAppState app = LauncherAppState.getInstance(this);
mModel = app.setLauncher(this);
mModel.startLoader()
}
LauncherModel setLauncher(Launcher launcher) {
getLocalProvider(mContext).setLauncherProviderChangeListener(launcher);
mModel.initialize(launcher);
return mModel;
}
public void initialize(Callbacks callbacks) {
synchronized (mLock) {
Preconditions.assertUIThread();
mCallbacks = new WeakReference<>(callbacks);
}
}
public void bindAllApplications(ArrayList<AppInfo> apps) {
mAppsView.getAppsStore().setApps(apps);
if (mLauncherCallbacks != null) {
mLauncherCallbacks.bindAllApplications(apps);
}
}
2.5 Android系统启动流程
步骤 |
简介 |
1.启动电源以及系统启动 |
加载引导程序BootLoader到RAM |
2.引导程序BootLoader |
系统OS拉起来 |
3.Linux内核启动 |
1.设置缓存、被保护存储器、计划列表、加载驱动;2.寻找 init.rc,启动 init 进程 |
4.init进程启动 |
1.初始化和启动属性服务;2.启动zygote进程 |
5.Zygote进程启动 |
1.创建java虚拟机,注册JNI方法;2.创建服务端Socket;3.启动SystemServer |
6.SystemServer进程启动 |
1.启动Binder线程池和SystemServiceManager;2.启动各种系统服务(AMS,PMS); |
7.Launcher启动 |
已安装的应用程序快捷图标显示到桌面上 |
1.按下电源,加载 BootLoader 把系统 OS 拉起来,Linux 内核启动,紧接着启动 init 进程,init 进程初始化和启动属性服务,并且启动 zygote进程,zygote 进程创建虚拟机加载JNI方法,创建服务端的 Socket,并且启动 SystemServer,SystemServer会启动Binder线程池和系统服务管理,包括AMS、PMS 等系统服务,最后,AMS 启动 Launcher,加载安装应用的图标。