您的位置:首页 > 移动开发 > Android开发

Android系统启动过程详解

2016-03-07 16:00 453 查看


Android系统启动过程详解

分类: Android 发布时间:
2014-04-07 01:29 ė6,857次浏览 6 0条评论

本文原创作者:Cloud Chou. 欢迎转载,请注明出处和本文链接

前言

一直想研究Android完整的启动过程,网上看了不少资料,也看了书上的一些说明,对这些观点有些怀疑,于是自己分析了系统启动的完整过程。从内核启动第一个用户程序init开始说起,直到Home应用的启动,每一步都有源代码展示。希望能解除读者对Android系统启动过程中的困惑,若有什么疑问,欢迎留言交流。本研究基于CM10.1源码,读者若能对照源代码查看效果会更好。

1) init启动servicemanager和 zygote两个service

Android底层是Linux内核,和linux类似,内核初始化后启动的第一个用户进程是init,它会解析init.rc脚本,启动init.rc里声明的service,并执行一些action。在init.rc里有启动Andriod空间的一些关键服务,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

#…
service servicemanager /system/bin/servicemanager
class core
user system
group system
critical
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart drm
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
#…

servicemanager负责管理所有的binder service, 这些binder service有native的,也有java的。native的binder service有surfaceflinger,drm,media等,java的binder service就有我们平常熟悉的很多管理服务了,ActivityManagerService,WindowManagerService,BatteryService,PowerManagerService,InputManagerService等等。service
manager并不负责这些binder service的创建,native的binder service大多由init启动init.rc里的service时创建并启动,java层的binder service大多由zygote创建并启动的,接下来会详细这些service是如何被启动的。

2) zygote service启动java层的ZygoteInit

zygote服务是java层所有程序进程的父进程,它是Android空间程序的孵化器,Android空间所有程序都是由zygote进程启动的。zygote service对应/system/bin/app_process程序,源代码位于frameworks/base/cmds/app_process/app_main.cpp,启动时的main函数代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1819
20
2122
23
24
25
26
27
28
29
30
3132
33
34
35
36
37
38
39
40
4142
43
44
45
46
47
48
49
50
5152
53
54
55
56
57
58
59
60
6162
63

int main(int argc, const char* const argv[])
{
//...
/*runtime就是dalvik虚拟机实例,启动Java层应用时,
*会fork 一个子进程,复制虚拟机,许多书上将runtime看作一个进程,
*然后再启动zygote进程,个人觉得这是错误的
*/
AppRuntime runtime;
//...
while (i < argc) {
const char* arg = argv[i++];
if (!parentDir) {
parentDir = arg;
/*init.rc启动app_main会设置参数--zygote*/
} else if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = "zygote"; //进程的名字
/*init.rc启动app_main会设置参数--start-system-server,
*表示需启动systemserver
*/
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
/*启动应用时会使用--application参数*/
} else if (strcmp(arg, "--application") == 0) {
application = true;
/*--nice-name=参数表示要设置的进程名字*/
} 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) {
/*虚拟机里启动com.android.internal.os.ZygoteInit,
*并传递参数start-system-server
*/
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer ? "start-system-server" : "");
} else if (className) {
/*若不是zygote,则启动的第一个类是com.android.internal.os.RuntimeInit,
*RumtimeInit初始化后会启动mClassName
*/
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.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
return 10;
}
//...
}

通过上述代码可知道zygote service将运行dalvik虚拟机,并在虚拟机里执行com.android.internal.os.ZygoteInit,还给它传递了参数start-system-server

3) ZygoteInit启动SystemServer

ZygoteInit启动时的相关源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1819
20
2122
23
24
25
26
27
28
29
30
3132
33
34

public static void main(String argv[]) {
{
try {
//...
//在某个描述符上监听连接请求,
//其它Android空间的程序的启动都是通过连接zygote才孵化出来的
registerZygoteSocket();
//...
if (argv[1].equals("start-system-server")) {
//启动SystemServer
startSystemServer();
} else if (!argv[1].equals("")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
//...
/*ZYGOTE_FORK_MODE默认为false,如果为true的话,每收到一个连接请求,
*就会建立一个新进程,然后再运行连接请求所要求执行的命令,此时会建立另一个新进程
*/
if (ZYGOTE_FORK_MODE) {
runForkMode();
} else {
//使用Select poll的方式来建立新进程,收到连接请求后,也会建立进程启动某个程序
runSelectLoopMode();
}

closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}

从上述代码可知道会调用startSystemServer以启动SystemServer,相关源代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1819
20
2122
23
24
25
26
27
28
29
30
3132
33
34
35
36
37
38
39
40
4142
43
44

private static boolean startSystemServer()
{
/* Hardcoded command line to start the system server */
//启动SystemServer使用的参数
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,3001,3002,3003,3004,3006,3007,3009",
"--capabilities=130104352,130104352",
"--runtime-init",
"--nice-name=system_server",
//注意:就是在这里设置要启动的SystemServer包名及类名,故此后续才能启动SystemServer
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
/*将args参数传给ZygoteConnection进行转化,--形式的参数将全部被接收
* 但是要启动的类的类名com.android.server.SystemServer会放在
*ZygoteConnection.Arguments的remainingArgs里,后来调用handleSystemServerProcess时会用到
*/
parsedArgs = new ZygoteConnection.Arguments(args);
/*添加额外运行参数*/
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/*开启新进程*/
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
/*调用handleSystemServerProcess会执行ZygoteConnection.Arguments的remainingArgs参数
*所指定的类,即com.android.server.SystemServer
*/
handleSystemServerProcess(parsedArgs);
}
}

ZygoteInit的startSystemServer会调用forkSystemServer,然后:

ZygoteInit.forkSystemServer -> Zygote.nativeForkSystemServer-> dalvik_system_Zygote.cpp 里的Dalvik_dalvik_system_Zygote_forkSystemServer-> forkAndSpecializeCommon->fork建立新进程

ZygoteInit的startSystemServer会调用handleSystemServerProcess来真正启动systemserver,相关源代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1819

private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
//...
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}
//启动systemserver时invokeWith为null
if (parsedArgs.invokeWith != null) {
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
null, parsedArgs.remainingArgs);
} else {
/*
* 启动systemserver时,parsedArgs.remainingArgs为com.android.server.SystemServer.
*/
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
}
}

然后的流程是

RuntimeInit.zygoteInit-> applicationInit,applicationInit的代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

private static void applicationInit(int targetSdkVersion, String[] argv)
{
//...
final Arguments args;
try {
//参数转换,系统启动时,argv里有一个参数是com.android.server.SystemServer
args = new Arguments(argv);
} catch (IllegalArgumentException ex) {
Slog.e(TAG, ex.getMessage());
// let the process exit
return;
}
//...
//终于在此启动了SystemServer
invokeStaticMain(args.startClass, args.startArgs)
}

4) SystemServer 启动过程

执行com.android.server.SystemServer时,main函数里会调用init1函数,init1函数是一个本地函数,init1的实现放在frameworks/base/services/jni/com_android_server_SystemServer.cpp里,对应的jni函数是android_server_SystemServer_init1,在该函数里会调用system_init,而system_init的实现是在frameworks/base/cmds/system_server/library/system_init.cpp,该函数的实现代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1819
20
2122
23
24
25
26
27
28
29
30
3132
33
34
35
36
37
38
39
40
4142
43
44
45
46
47

extern "C" status_t system_init()
{
//...
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p\n", sm.get());
sp<GrimReaper> grim = new GrimReaper();
sm->asBinder()->linkToDeath(grim, grim.get(), 0);
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// Start the SurfaceFlinger
SurfaceFlinger::instantiate();
}
property_get("system_init.startsensorservice", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// Start the sensor service
SensorService::instantiate();
}
// And now start the Android runtime.  We have to do this bit
// of nastiness because the Android runtime initialization requires
// some of the core system services to already be started.
// All other servers should just start the Android runtime at
// the beginning of their processes's main(), before calling
// the init function.
ALOGI("System server: starting Android runtime.\n");
AndroidRuntime* runtime = AndroidRuntime::getRuntime();
ALOGI("System server: starting Android services.\n");
JNIEnv* env = runtime->getJNIEnv();
if (env == NULL) {
return UNKNOWN_ERROR;
}
jclass clazz = env->FindClass("com/android/server/SystemServer");
if (clazz == NULL) {
return UNKNOWN_ERROR;
}
//反过来调用Java里SystemServer的init2函数
jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");
if (methodId == NULL) {
return UNKNOWN_ERROR;
}
env->CallStaticVoidMethod(clazz, methodId);
ALOGI("System server: entering thread pool.\n");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
ALOGI("System server: exiting thread pool.\n");
}

5) 启动Java层的各种binder service

调用SystemServer的init2函数后,会开启新线程android.server.ServerThread,在新线程里会启动各种Java层的binder service,并在service manager里注册,这些Service大多开启了新线程运行,故此都是systemserver的子线程,添加的Service列表如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1819
20
2122
23
24
25
26
27
28
29
30
3132
33
34
35
36
37
38
39
40
4142
43
44
45
46
47
48
49
50
51

ServiceManager.addService("entropy", new EntropyMixer());
ServiceManager.addService(Context.POWER_SERVICE, power);
ServiceManager.addService(Context.DISPLAY_SERVICE, display, true);
ServiceManager.addService("telephony.registry", telephonyRegistry);
ServiceManager.addService(Context.SCHEDULING_POLICY_SERVICE,
ServiceManager.addService(Context.USER_SERVICE,UserManagerService.getInstance());
ServiceManager.addService(Context.ACCOUNT_SERVICE, accountManager);
ServiceManager.addService("battery", battery);
ServiceManager.addService("vibrator", vibrator);
ServiceManager.addService(Context.ALARM_SERVICE, alarm);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
ServiceManager.addService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, bluetooth);
ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,new AccessibilityManagerService(context));
ServiceManager.addService("mount", mountService);
ServiceManager.addService("lock_settings", lockSettings);
ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, devicePolicy);
ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
ServiceManager.addService(Context.CLIPBOARD_SERVICE,new ClipboardService(context));
ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);
ServiceManager.addService(Context.TEXT_SERVICES_MANAGER_SERVICE, tsms);
ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);
ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
ServiceManager.addService(Context.WIFI_P2P_SERVICE, wifiP2p);
ServiceManager.addService(Context.WIFI_SERVICE, wifi);
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
ServiceManager.addService(Context.NSD_SERVICE, serviceDiscovery);
ServiceManager.addService(Context.THROTTLE_SERVICE, throttle);
ServiceManager.addService("fm_receiver",new FmReceiverService(context));
ServiceManager.addService("fm_transmitter",new FmTransmitterService(context));
ServiceManager.addService(Context.UPDATE_LOCK_SERVICE,new UpdateLockService(context));
ServiceManager.addService(Context.PROFILE_SERVICE, profile);
ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification);
ServiceManager.addService(DeviceStorageMonitorService.SERVICE,
ServiceManager.addService(Context.LOCATION_SERVICE, location);
ServiceManager.addService(Context.COUNTRY_DETECTOR, countryDetector);
ServiceManager.addService(Context.SEARCH_SERVICE,new SearchManagerService(context));
ServiceManager.addService(Context.DROPBOX_SERVICE,new DropBoxManagerService(context, new File("/data/system/dropbox")));
ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);
ServiceManager.addService(Context.AUDIO_SERVICE, new AudioService(context));
ServiceManager.addService(Context.USB_SERVICE, usb);
ServiceManager.addService(Context.SERIAL_SERVICE, serial);
ServiceManager.addService(Context.BACKUP_SERVICE,new BackupManagerService(context));
ServiceManager.addService(Context.APPWIDGET_SERVICE, appWidget);
ServiceManager.addService("diskstats", new DiskStatsService(context));
ServiceManager.addService("samplingprofiler", new SamplingProfilerService(context));
ServiceManager.addService("commontime_management", commonTimeMgmtService);
ServiceManager.addService(DreamService.DREAM_SERVICE, dreamy);
ServiceManager.addService("assetredirection", new AssetRedirectionManagerService(context));
ServiceManager.addService("pieservice", pieService);

上述并没有看到将ActivityManagerService添加到servicemanager管理,它的添加过程比较特别。在线程android.server.ServerThread里会调用ActivityManagerService.setSystemProcess();setSystemProcess函数的代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1617

public static void setSystemProcess() {
//…
ActivityManagerService m = mSelf;
ServiceManager.addService("activity", m, true);
ServiceManager.addService("meminfo", new MemBinder(m));
ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
ServiceManager.addService("dbinfo", new DbBinder(m));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(m));
}
ServiceManager.addService("permission", new PermissionController(m));
ApplicationInfo info =
mSelf.mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS);
mSystemThread.installSystemApplicationInfo(info);
//…
}

可以看到ActivityManagerService采用了单例模式,并调用ServiceManager.addService(“activity”, m, true);将ActivityManagerService交给servicemanager管理,在ActivityManagerService里还添加了别的binder service,像MemBinder,GraphicsBinder,DbBinder。

最后会调用Looper.loop();进入loop循环,等待和别的程序通信。

6) 启动系统界面

线程android.server.ServerThread里有如下代码:

1
2
3
4
5
6
7
8

ActivityManagerService.self().systemReady(new Runnable() {
public void run() {
Slog.i(TAG, "Making services ready");

if (!headless) startSystemUi(contextF);
//...
}
}

startSystemUi就是用于启动系统界面的,代码如下:

1
2
3
4
5
6
7

static final void startSystemUi(Context context) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
//Slog.d(TAG, "Starting service: " + intent);
context.startServiceAsUser(intent, UserHandle.OWNER);
}

这样便启动了com.android.systemui应用,该应用将启动PowerUI和RingtonePlayer两个线程。

7) 启动Home 程序

线程android.server.ServerThread里有如下代码:

1
2
3
4
5
6
7

//…
ActivityManagerService.self().systemReady(new Runnable() {
public void run() {
//…
}
});
//…

ActivityManagerService.self().systemReady有如下代码:

1
2
3

//…
mMainStack.resumeTopActivityLocked(null);
//…

ActivityStack. resumeTopActivityLocked()有如下代码:

1

resumeTopActivityLocked(prev, null);

resumeTopActivityLocked的实现有如下代码:

1
2
3
4
5
6
7
89
10

//…
if (next == null) {
// There are no more activities!  Let's just start up the
// Launcher...
if (mMainStack) {
ActivityOptions.abort(options);
return mService.startHomeActivityLocked(mCurrentUser);
}
}
//…

mService类型是ActivityManagerService,ActivityManagerService. startHomeActivityLocked的实现有如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1819
20
2122
23
24
25
26
27
28
29

boolean startHomeActivityLocked(int userId) {
//…
Intent intent = new Intent(
mTopAction,
mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
//这里便添加了Intent.CATEGORY_HOME,
//所有的Home应用都会都带有该类型的Activity,只有这样才会被认为是Home应用
if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);
}
ActivityInfo aInfo =
resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
intent.setComponent(new ComponentName(
aInfo.applicationInfo.packageName, aInfo.name));
// Don't do this if the home app is currently being
// instrumented.
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid);
if (app == null || app.instrumentationClass == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
mMainStack.startActivityLocked(null, intent, null, aInfo,
null, null, 0, 0, 0, 0, null, false, null);
}
}
}

这样先找到使用Intent.CATEGORY_HOME声明的Activity组件,然后再调用mMainStack.startActivityLocked启动该Activity。

system server启动Home程序总结:

android.server.ServerThread->ActivityManagerService.self().systemReady->mMainStack.resumeTopActivityLocked->resumeTopActivityLocked-> mService.startHomeActivityLocked-> intent.addCategory(Intent.CATEGORY_HOME);mMainStack.startActivityLocked

总结

内核初始化好后,运行的第一个用户程序是init,init将启动init.rc里声明的多个service,跟Android空间相关的有servicemanager和zygote,servicemanager负责管理所有的binder service,zygote负责孵化所有Android空间的程序。zygote service对应的程序是app_process,不过加了一些启动参数,所以它会启动Java层的ZygoteInit,在ZygoteInit里会启动SystemServer,SystemServer分为两个阶段:本地的init1和Java层的init2,init2里会启动线程android.server.ServerThread。在android.server.ServerThread线程里会启动Java层的各种binder
service,比如ActivityManagerService,PackageManagerService,WindowManagerService。然后调用ActivityManagerService的systemReady方法,在该方法里会启动系统界面以及Home程序。

0android 启动
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: