android init进程分析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android init进程分析相关的知识,希望对你有一定的参考价值。

android的init进程用来启动zygote进程,用来启动android世界。
init进程的源码在顶层目录的/system/core/init
使用 find -name Android.mk -exec grep -l "init" {} \;来查找源码,接下来的android服务程序也是使用这个指令来查找源码。


/system/core/init/init.c
整个init进程的入口函数
669 int main(int argc, char **argv)
init_parse_config_file("/init.rc");
snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
722 init_parse_config_file(tmp);
解析两个文件脚本文件。解析完之后按条件触发事件,最后程序进入死循环,轮询监控属性、按键、信号

 

android里面两个重要的进程为。zygote和servermanger两个服务。
431 service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
432 class main
433 socket zygote stream 666
434 onrestart write /sys/android_power/request_state wake
435 onrestart write /sys/power/state on
436 onrestart restart media
437 onrestart restart netd
438


find -name Android.mk -exec grep -l "app_process" {} \;用来查找zygote服务的源码。
源码路径/android4.0/frameworks/base/cmds/app_process$
app_main.cpp为zygote进程的程序入口 。
不管是java、c++还是c程序的入口都是main

zygote = true;
niceName = "zygote";
startSystemServer = true;


if (zygote) {
189 runtime.start("com.android.internal.os.ZygoteInit", "start-system-server");


调用runtime的start方法,在runtime的祖先类内定义。
在frameworks/base/core/jni/AndroidRuntime.cpp
99 void AndroidRuntime::start(const char* className, const char* options)
800 {
/* start the virtual machine */
831 JNIEnv* env;
832 if (startVm(&mJavaVM, &env) != 0) {
833 return;
834 }
835 onVmCreated(env);
836
837 /*

com/android/internal/os/ZygoteInit"

为接下来进入java环境准备参数,准备一个java环境string数组
855 stringClass = env->FindClass("java/lang/String");
856 assert(stringClass != NULL);
857 strArray = env->NewObjectArray(2, stringClass, NULL);
858 assert(strArray != NULL);
859 classNameStr = env->NewStringUTF(className);
860 assert(classNameStr != NULL);
861 env->SetObjectArrayElement(strArray, 0, classNameStr);
862 optionsStr = env->NewStringUTF(options);
863 env->SetObjectArrayElement(strArray, 1, optionsStr);

strArray[2] = {"com.android.internal.os.ZygoteInit", "start-system-server"};


866 * Start VM. This thread becomes the main thread of the VM, and will
867 * not return until the VM exits.
868 */
869 char* slashClassName = toSlashClassName(className);包名转换为路径
870 jclass startClass = env->FindClass(slashClassName); 在c环境找java类文件
871 if (startClass == NULL) {
872 LOGE("JavaVM unable to locate class ‘%s‘\n", slashClassName);
873 /* keep going */
874 } else {
875 jmethodID startMeth = env->GetStaticMethodID(startClass, "main", 在找到的java文件内找void main(string[])方法
876 "([Ljava/lang/String;)V");
877 if (startMeth == NULL) {
878 LOGE("JavaVM unable to find main() in ‘%s‘\n", className);
879 /* keep going */
880 } else {
881 env->CallStaticVoidMethod(startClass, startMeth, strArray); 从c环境跳到java世界并带有参数
882

 

java世界:
find -name main
android4.0/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java android、世界下整个java世界的开始

if (argv[1].equals("start-system-server")) {
536 startSystemServer(); 根据传递的参数 决定是否启动system_server服务
system_server服务的源码在:android4.0/frameworks/base/services/java/com/android/server/SystemServer.java


--------------->>>>>>
native public static void init1(String[] args); 被native修饰过的函数就是一个jni函数,在c、环境下。


SystemServer.java找到他的入口。main

System.loadLibrary("android_servers"); 从java世界跳转到c环境,需要先将c环境的库文件进行加载,加载好了之后再进行跳转。
init1(args);

find -name Android.mk -exec grep -l "android_servers" {} \;

/android4.0/frameworks/base/services/jni/com_android_server_SystemServer.cpp

static JNINativeMethod gMethods[] = {
35 /* name, signature, funcPtr */
36 { "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 }, jni提前写好了关系,将java调用的本地代码和c里面的执行函数进行关联
37 };


因此执行的是android_server_SystemServer_init1函数
24 extern "C" int system_init(); 说明来自另外一个c++文件名为system_init.cpp


find -name system_init.cpp 文件在
android4.0/frameworks$ /base/cmds/system_server/library/system_init.cpp


system_init启动了两个服务SensorService、SurfaceFlinger
并且调回java,执行init2();
jclass clazz = env->FindClass("com/android/server/SystemServer");
94 if (clazz == NULL) {
95 return UNKNOWN_ERROR;
96 }
97 jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");
98 if (methodId == NULL) {
99 return UNKNOWN_ERROR;
100 }
101 env->CallStaticVoidMethod(clazz, methodId); 回到java环境,执行init2

 

以上是关于android init进程分析的主要内容,如果未能解决你的问题,请参考以下文章

Android init 启动进程分析

Android O: init进程启动流程分析(阶段三)

Android O: init进程启动流程分析(阶段二)

Android6.0系统启动流程分析一:init进程

Android O: zygote进程分析

Android 4.4 Init进程分析二:init.rc文件的解析