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,加载安装应用的图标。