Android系统启动源代码调查分析

更新时间:2024-05-18 23:38:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

Android系统启动调查。

目的:Android程序入口在哪里?Mainifest配置文件如何加载实例化?从系统层到应用层如何使用?

目标从系统角度来了解Android启动过程,通过下载源代码并且根据源代码从底层开始跟踪,跟着方法走一遍Android启动过程。了解Zygote进程是什么?

开机一开始:Linux启动这一层,主要包括了两块:BootLoader(嵌入式系统的引导程序)和Kernel(Linux内核层,驱动层) 第二块:Android系统启动。

我们都知道,Linux系统启动,定义了一个Init.rc这个系统启动的配置文件(放在System/bin文件下面)。

Init.rc启动的时候,最开始启动了SystemManager守护进程,它的源代码是一个Java文件,守护进程是一个与界面无关,会持续运行在后台,用来接收响应,并且维持系统运营的。

在启动servicemanager的同时,再来启动Zygote,Zygote实际上启动的是:app_main.cpp的系统文件.这个文件的main()方法,会调用Android_Runtime.cpp的文件中的start()方法,这个方法通过JNI机制,来调用ZygoteInit.java孵化器初始文件,这个文件的Main()函数,将会去调用所有进程。

这个ZygoteInit文件的main()函数,这个函数通过JNI机制调用了FrameWrok中的SystemServer文件,这个文件有三个函数:main(),init1()和init2()方法。

Init1()方法会通过JNI机制再去调用com_Android__server_SystemService.java的原生态文件,去实现系统初始化的操作,(调用System_init.cpp)。

当系统初始化工作做完之后,系统反过来会调用SystemServer文件下面的init2()方法,会通过runtime方法调用ServerThread进程去调用激活其他的所有进程。

第三块:应用程序启动(下次再讲)。

使用工具:【代码分析工具】source Insight 【源代码】 Android 源代码包

操作步骤:

在下载好Android SDK 安装包之后 (如果没有下载好请移步这里)

【配置代码分析工具】

打开source Insight 软件,来配置Android源代码。

“项目”→“新建项目”

在“新项目名”填写:“Android 14”(Android 第14个版本,代表Android V4.0.3) 在“项目文件储存位置”填写:SDK源代码包的位置

继续进行配置,点击确定。

选中右边的所有文件夹,点击“添加所有”按钮,将这个版本的源代码全部导入。

这就是守护进程中的源代码之一,start()方法 ServiceManager::ServiceManager() { }

int ServiceManager::start(const char *name) { //如果进程已经启动,那么打印日志:“XX进程已经启动” if (isRunning(name)) {

SLOGW(\ return 0; }

SLOGD(\ property_set(\

int count = 200; while(count--) { sched_yield();

if (isRunning(name)) break; }

if (!count) {

SLOGW(\ errno = ETIMEDOUT; return -1; }

SLOGD(\ return 0; }

再来看同时启动的app_main的源代码,我们去查看一下它的main函数

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

mArgLen += strlen(argv[i]) + 1; }

mArgLen--;

AppRuntime runtime; const char *arg; const char *argv0;

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);

// Next arg is parent directory if (i < argc) {

runtime.mParentDir = argv[i++]; }

// Next arg is startup classname or \ if (i < argc) {

arg = argv[i++];

if (0 == strcmp(\

bool startSystemServer = (i < argc) ?

strcmp(argv[i], \ setArgv0(argv0, \ //设置了一个进程名叫zygote的进程,通过runtime来启动ZygoteInit文件中的startSystemServer方法 set_process_name(\

runtime.start(\ } else {

set_process_name(argv0);

runtime.mClassName = arg;

// Remainder of args get passed to startup class main() runtime.mArgC = argc-i; runtime.mArgV = argv+i;

LOGV(\ getpid(), runtime.getClassName()); runtime.start(); } } else {

LOG_ALWAYS_FATAL(\ fprintf(stderr, \ app_usage(); return 10; } }

调查一下runtime的类。AppRuntime,这就是android系统的运行时类,它启动了zygote孵化器进程,用来孵化Davlik虚拟机的。

我们再去看看 runtime.start(\所涉及到的ZygoteInit文件。

找到ZygoteInit文件(FrameWork里面的一个java类)。先去看看Main函数。

public static void main(String argv[]) { try {

VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024); // Start profiling the zygote initialization. SamplingProfilerIntegration.start(); registerZygoteSocket();

EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,SystemClock.uptimeMillis()); preloadClasses();

//cacheRegisterMaps(); preloadResources();

EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis());

// Finish profiling the zygote initialization.

SamplingProfilerIntegration.writeZygoteSnapshot(); // Do an initial gc to clean up after startup gc();

// If requested, start system server directly from Zygote if (argv.length != 2) {

throw new RuntimeException(argv[0] + USAGE_STRING); }

if (argv[1].equals(\ //如果输入参数为真,我们就启动系统服务 startSystemServer();

} else if (!argv[1].equals(\

throw new RuntimeException(argv[0] + USAGE_STRING); }

Log.i(TAG, \ if (ZYGOTE_FORK_MODE) { //如果孵化器一直是交叉模式,就启动运行交叉模式函数;否则就选择另一个循环模式 runForkMode(); } else {

runSelectLoopMode(); }

closeServerSocket();

} catch (MethodAndArgsCaller caller) { caller.run();

} catch (RuntimeException ex) {

Log.e(TAG, \ closeServerSocket(); throw ex; } }

我们继续查看,如果参数为真的情况下,ZygoteInit文件中的,startSystemServer()函数的源代码。

/**

* Prepare the arguments and fork for the system server process. */

private static boolean startSystemServer()

throws MethodAndArgsCaller, RuntimeException { /* Hardcoded command line to start the system server */ String args[] = {

\ \

\ \ \

\

\com.android.server.SystemServer\ //这个虚拟机的名字叫system Server };

ZygoteConnection.Arguments parsedArgs = null; int pid; try {

parsedArgs = new ZygoteConnection.Arguments(args); /*

* Enable debugging of the system process if *either* the command line flags * indicate it should be debuggable or the ro.debuggable system property * is set to \ */

int debugFlags = parsedArgs.debugFlags;

if (\ debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;

/* Request to fork the system server process */ pid = Zygote.forkSystemServer(

parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, debugFlags, null,

parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); }

/* For child process */ if (pid == 0) {

handleSystemServerProcess(parsedArgs); }

return true; }

我们继续去查看 system Server的源代码

找这个函数里面的main函数:

/**

* This method is called from Zygote to initialize the system. This will cause the native * services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back * up into init2() to start the Android services. */

native public static void init1(String[] args); //Init1()函数却是个空函数

public static void main(String[] args) {

if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { // If a device's clock is before 1970 (before 0), a lot of // APIs crash dealing with negative numbers, notably // java.io.File#setLastModified, so instead we fake it and // hope that time from cell towers or NTP fixes it // shortly.

Slog.w(TAG, \

SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); }

if (SamplingProfilerIntegration.isEnabled()) { SamplingProfilerIntegration.start(); timer = new Timer();

timer.schedule(new TimerTask() { @Override

public void run() {

SamplingProfilerIntegration.writeSnapshot(\ }

}, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL); }

// The system server has to run all of the time, so it needs to be // as efficient as possible with its memory usage.

VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

System.loadLibrary(\

init1(args); // main()函数中,会调用到 init1()的方法。 }

public static final void init2() {

Slog.i(TAG, \ Thread thr = new ServerThread();

thr.setName(\ thr.start(); }

因为通过调查发现,SystemServer文件的main()函数调用的init1()函数,是一个空方法,native public static void init1(String[] args);

但是根据JNI调用机制,我们可以在同名文件夹(framework/base/services/)下找到JNL目录,然后找到和系统相关的com_android_server_SystemServer.java文件

这里面可以看见

使用“C”的动态链接嗲用system_init 的方法。它去回调Init2的方法

我们继续看看SystemServer方法的Init2()方法是看什么用的。

去调查一下ServerThread()方法是干什么用的?这个内部类ServerThread就是启动,并且实例化每一个系统进程的线程类

本文来源:https://www.bwwdw.com/article/pa17.html

Top