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就是启动,并且实例化每一个系统进程的线程类
正在阅读:
Android系统启动源代码调查分析05-18
拉丁美洲社会制度特征与组织的人际关系模式07-20
济南版五年级安全教育教案10-22
解决合并同类项中两类重要问题的方法08-06
哲学解释学下的思想政治理论课研究12-12
如何做一个成功的下属的学习心得03-15
现代科学技术概论答案 刘金寿版05-25
传热学第五章答案-第五版10-09
像经济学家一样思考习题及答案03-29
期末复习题 - SDH部分11-02
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 源代码
- Android
- 启动
- 调查
- 分析
- 系统
- uml银行用例图
- 航海学新增1
- 《管理学原理与方法》
- 八年级生物实验教学计划(上学期)
- 最佳路径教学案
- 燃气锅炉房安全管理制度
- 冷冻结晶技术+膜过滤组合工艺处理硫酸钠废水的优越性
- 教案235 植物的一生1
- 金融法规案例
- B.3.1 施工进度计划报审表
- 1.3 噪声及其控制 教案 苏科版八年级上册(2012年秋)5
- 2010届高考历史古代东西方的政治制度 - 图文
- 2018年最新整合-淘宝售前咨询规范-咨询技巧认证考试答案全
- 智能手机充电器开发设计可行性研究报告
- 组织文化与组织环境
- 《辩证唯物主义和历史唯物主义原理(第五版)》笔记
- 2011中级经济师经济基础考点汇总
- 高一政治下学期第一次四校联考
- 计算机财务管理答案终稿
- 教育学习文章市委zd委XX年党建工作总结