Framework基础:Android系统经过是怎么来的?彩民之家

2019-09-18 21:55 来源:未知

app_process 进程##

/frameworks/base/cmds/app_process/app_main.cppapp_process 是init进度后步入java世界的入口,他是init进程经过解释上面包车型地铁rc文件,来运维一个bin文件发出的。/system/core/rootdir/init.zygote32.rc

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

可以看出给app_process 的main函数字传送入了-Xzygote /system/bin --zygote --start-system-server参数,使用那个参数构建了AndroidRuntime。

AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));

还要给AndroidRuntime参加了option选项Xzygote,具体怎么进入那几个参数还不太明白,揣测是标识当前AndroidRuntime要进行zygote之类的啊。

runtime.addOption(strdup;

下一场塑造了参数args,参数富含start-system-server,--abi-list=arm64-v8a。start-system-server代表接下去要运转system_server,arm64-v8a是cpu的架构,估摸底层要用到。

彩民之家论坛9066777 1构建参数.png

最终,参数args通过AndroidRuntime被传送给ZygoteInit,进入ZygoteInit的main函数,最初受精卵的初阶化。

runtime.start("com.android.internal.os.ZygoteInit", args, zygote);

上边是自己透过在文书/frameworks/base/cmds/app_process/app_main.cpp增添log实行的跟踪。

彩民之家论坛9066777 2Paste_Image.png

   /**
     * Finish remaining work for the newly forked system server process.
     * 完成新建的system server进程的剩余工作
     */
    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {

        closeServerSocket();//关闭从Zygote复制过来的socket 

        // set umask to 0077 so new files and directories will default to owner-only permissions.
        Libcore.os.umask(S_IRWXG | S_IRWXO);//设置文件的默认权限,去除文件所有者之外的权限

        if (parsedArgs.niceName != null) {
            Process.setArgV0(parsedArgs.niceName);
        }

        if (parsedArgs.invokeWith != null) {
            WrapperInit.execApplication(parsedArgs.invokeWith,
                    parsedArgs.niceName, parsedArgs.targetSdkVersion,
                    null, parsedArgs.remainingArgs);
        } else {
            /*
             * Pass the remaining arguments to SystemServer.传递剩下的参数给SystemServer
             */
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
        }

        /* should never reach here */
    }
1.2. 剖判运行参数
  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;
    } else if (strcmp(arg, "--application") == 0) {
        application = true;
    } else if (strncmp(arg, "--nice-name=", 12) == 0) {
        niceName.setTo(arg   12);
    } else if (strncmp(arg, "--", 2) != 0) {
        className.setTo(arg);
        break;
    } else {
        --i;
        break;
    }
}

从init.rc文件中传播的参数是-Xzygote /system/bin --zygote --start-system-server --socket-name=zygote,解析后:

  • zygote = true;
  • niceName = zygoe;
  • startSystemServer = true;

init进程##

Andriod的木本是linux,手机首先运行linux内核,内核第贰个进度是init进度,为1号经过。如下图

彩民之家论坛9066777 3Paste_Image.png

Init的主要任务是:

1.3. 执行ZygoteInit类
if (zygote) {
    runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
    runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} 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经过剖析参数后为true, 所以会进行runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
AndroidRuntime的start方法完结在<Android源代码目录>/frameworks/base/core/jni/AndroidRuntime.cpp中,
/*
* Start the Android runtime. This involves starting the virtual machine
* and calling the "static void main(String[] args)" method in the class
* named by "className".
*
* Passes the main function two arguments, the class name and the specified
* options string.
/
void AndroidRuntime::start(const char
className, const Vector<String8>& options, bool zygote)
{
... 运转设想机,注册jni等
char* slashClassName = toSlashClassName(className);
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'n", slashClassName);
/* keep going /
} else {
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'n", className);
/
keep going */
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray);

#if 0
        if (env->ExceptionCheck())
            threadExitUncaughtException(env);
#endif
        }
    }
      ...
}

其一方法会运维Android运转情形,意味着它会运转android设想机,并调用参数中className中的man方法。
从传出的com.android.internal.os.ZygoteInit 类中找到main函数,即调用ZygoteInit.java类中的main方法。AndroidRuntime及后边的法子都以native的法子,而此时调用的ZygoteInit.main方法是java的点子,到此处咱们就进去了java的世界。。。

调用暗暗提示图如下:

彩民之家论坛9066777 4

20150624093319_591.png

受精卵ZygoteInit##

ZygoteInit是三个java文件,表明在那步java运营的功底已经济建设立好了。小编想是地点的AndroidRuntime新建后,手提式有线话机就具备了运转java文件的条件。ZygoteInit作为第一个手机中运转的java文件,经常被称作受精卵。/frameworks/base/core/java/com/android/internal/os/ZygoteInit.javaZygoteInit文件的进口是何许呢?搞过java的都清楚,当然是main函数啦。大家得以那样敞亮,上边的app_process 施行了四个java的周转命令,运营ZygoteInit类。

java ZygoteInit

ZygoteInit类其实在表哥大以贰个dex文件存在(实际他保存在framework.jar中)。大家看看ZygoteInit的main函数

 public static void main(String argv[]) { try { ............... boolean startSystemServer = false; String socketName = "zygote"; String abiList = null; for (int i = 1; i < argv.length; i  ) { if ("start-system-server".equals { startSystemServer = true; } else if (argv[i].startsWith(ABI_LIST_ARG)) { abiList = argv[i].substring(ABI_LIST_ARG.length; } else if (argv[i].startsWith(SOCKET_NAME_ARG)) { socketName = argv[i].substring(SOCKET_NAME_ARG.length; } else { throw new RuntimeException("Unknown command line argument: "   argv[i]); } } registerZygoteSocket(socketName); preload(); //资源预加载 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis; if (startSystemServer) { //开启systemServer startSystemServer(abiList, socketName); } closeServerSocket(); .......................... } catch (MethodAndArgsCaller caller) { caller.run(); } catch (RuntimeException ex) { Log.e(TAG, "Zygote died with exception", ex); closeServerSocket(); throw ex; } }

能够看出,首要进行了财富的预加载,然后运转系统开展SystemServer。从而系统经过就跑起来了。

彩民之家论坛9066777 5SystemServer.png

1.init扩充运行bin文件app_process ,开启了app_process 进程2.app_process 创建了java运转的功底蒙受AndroidRuntime,并产生受精卵ZygoteInit。3.受精卵ZygoteInit生下了小外孙子systemServer。系统经过运营完成。

看了相当的多有关博客,明日也来自身梳理以下~~~
Android从Linux系统运转

1. 起动流程

/init.zygote64_32.rc文本中运营Zygote的内容如下:

    service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
    class main
    priority -20
    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
    writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks

在<Android源代码目录>/system/core/rootdir/ 目录下得以看来init.zygote32.rc、init.zygote32_64.rc、init.zygote64.rc、init.zygote64_32.rc等文件,那是因为Android5.0起来帮助64人的编写翻译,所以Zygote进度本人也可以有三拾贰个人和六十五个人版本。

从地点定义看到Zygote进度的可执行文件是app_process(@frameworks/base/cmds/app_process/app_main.cpp)。
接下去剖析main()函数的流程。

Android的体系经过是SystemServer,他是怎么来的吧?

  1. Linux的init在开发银行若干守护进程之后,就开发银行了Android的runtime和zygote,Zygote进程担任后续Android应用程序框架层的其余进度的创制和开发银行工作。

  2. Zygote进度会首先成立一个SystemServer进度,SystemServer进度负担运维系统的要害服务,如包管理服务PackageManagerService和应用程序组件管理服务ActivityManagerService。

  3. 当大家要求运营一个Android应用程序时,ActivityManagerService会通过Socket进度间通讯机制,文告Zygote进度为那么些应用程序创设一个新的经过。
1.4. ZygoteInit的main方法

ZygoteInit定义在/<Android源代码目录>/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java。

public static void main(String argv[]) {
    try {
        ...
        registerZygoteSocket(socketName);
        preload();
        if (startSystemServer) {
            startSystemServer(abiList, socketName);
        }
        runSelectLoop(abiList);
        ...
    } catch (MethodAndArgsCaller caller) {
        caller.run();
    } catch (RuntimeException ex) {
        Log.e(TAG, "Zygote died with exception", ex);
        closeServerSocket();
        throw ex;
    }
}

关键专门的学问:
(1) 注册Zygote的socket监听端口,应用接收运营应用程序的音信
(2) 调用preload()方法加载系统财富,蕴涵预加载类,Framework能源等
(3) 调用startSystemServer()方法运维SystemServer进度
(4) 调用runSelectLoop()方法步向监听和接收音讯循环

可知SystemServer是Zygote运行的第多个经过。

彩民之家论坛9066777 6小鱼.png

源码:frameworks/base/services/java/com/android/server/SystemServer.java

0. 前言

上节小说的终极聊到了init以service的法门运营了Zygote进度。那节小说首要讲Zygote进度的开行流程。

对于Zygote进度的描述如下:
在Android中,zygote是任何种类成立新历程的骨干装置。zygote进度在内部会先运转Dalvik设想机,继而加载一些不能缺少的系统财富和系统类,最后步向一种监听状态。在一而再的运维中,当别的系统模块(比如AMS)希望成立新进度时,只需向zygote进度发出央求,zygote进度监听到该央求后,会相应地“不一样”出新的进程,于是这几个新进度在新兴之时,就自然具备了友好的Dalvik设想机以及系统能源。

/*
 * Start the Android runtime.  This involves starting the virtual machine
 * and calling the "static void main(String[] args)" method in the class
 * named by "className".
 *
 * Passes the main function two arguments, the class name and the specified
 * options string.
 */
//上面的解释是开始android运行时环境。将开始虚拟机,然后用类似反射的机制去调用类名为参数className的main()方法!
void AndroidRuntime::start(const char* className, const char* options)
{
    if (strcmp(options, "start-system-server") == 0) {
        /* track our progress through the boot sequence */
        const int LOG_BOOT_PROGRESS_START = 3000;
        LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
                       ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
    }

    const char* rootDir = getenv("ANDROID_ROOT");
    if (rootDir == NULL) {
        rootDir = "/system";
        if (!hasDir("/system")) {
            LOG_FATAL("No root directory specified, and /android does not exist.");
            return;
        }
        setenv("ANDROID_ROOT", rootDir, 1);
    }

    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    if (startVm(&mJavaVM, &env) != 0) {//开启虚拟机
        return;
    }
    onVmCreated(env);

    /*
     * Register android functions. 注册本地native函数
     */
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android nativesn");
        return;
    }
    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;
    jstring optionsStr;

    stringClass = env->FindClass("java/lang/String");
    assert(stringClass != NULL);
    strArray = env->NewObjectArray(2, stringClass, NULL);
    assert(strArray != NULL);
    classNameStr = env->NewStringUTF(className);
    assert(classNameStr != NULL);
    env->SetObjectArrayElement(strArray, 0, classNameStr);
    optionsStr = env->NewStringUTF(options);
    env->SetObjectArrayElement(strArray, 1, optionsStr);

    /*
     * Start VM.  This thread becomes the main thread of the VM, and will
     * not return until the VM exits.
     */
    //激活虚拟机,当前线程变成虚拟机下的主线程。
    char* slashClassName = toSlashClassName(className);
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'n", slashClassName);
    } else {
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'n", className);
            /* keep going */
        } else {
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
        }
    }

}

更多

上边根本讲了Zygote的起步流程,其实还也是有为数非常的多供给去询问的地点,如 SystemServer是何等运行的, 已经Zygote在起步新的经过时会做怎么着管理等,不时间了再去探听。。。

打听了这几个音讯之后,大家就精晓Zygote进度要实施的程序正是system/bin/app_process了,它的源代码位于frameworks/base/cmds/app_process/app_main.cpp文件中,入口函数是main。

1.1. 创建AppRuntime对象

AppRuntime是在app_process中定义的类,承接了系统的AndroidRuntime类,AndroidRuntime类的非常重要成效是创制和开头化虚构机。

彩民之家论坛9066777 7

参考

网络有为数相当多博客对这一部分的打听都相比详细,所以这篇文章只是个人粗浅的上学,还得继续。。

http://blog.csdn.net/luoshengyang/article/details/6768304
http://www.open-open.com/lib/view/open1435109640966.html
http://blog.csdn.net/andyhuabing/article/details/7349986

2012111315182764.jpg

源码在/system/core/init/init.c

看看init.rc脚本

用作医生和护师进度
剖判核推行init.rc文件
转移设备节点
属性服务

public static void main(String argv[]) {
        try {
            // Start profiling the zygote initialization.
            SamplingProfilerIntegration.start();

            registerZygoteSocket();
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                SystemClock.uptimeMillis());
            preload();
            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[1].equals("start-system-server")) {
                startSystemServer();//启动system_server进程  
            } else if (!argv[1].equals("")) {
                throw new RuntimeException(argv[0]   USAGE_STRING);
            }
          ......
            runSelectLoop();
            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            caller.run();
        } catch (RuntimeException ex) {
            ......
        }
    }

ps:(1)这里描述了孵蛋机zygote的起步(init是zygote的父进度,而系统服务进程system_server和另外全体的com.xxx结尾的应用程序都以从zygote fork 而来)。
(2)后边的机要字service告诉init进度创建三个名称为"zygote"的长河,这些zygote进度要执行的程序是/system/bin/app_process,前面是要传给app_process的参数。最终的一密密麻麻onrestart关键字表示这几个zygote进程重启时须求推行的通令。

SystemServer创立之后交给handleSystemServerProcess管理!

第一看一下参数:

实质上实行com.android.internal.os.ZygoteInit类的main()(源码地址frameworks/base/core/java/com/android/internal/os/ZygoteInit.java):

int main(int argc, char* const argv[])
{
     ......
    // These are global variables in ProcessState.cpp
    mArgC = argc;
    mArgV = argv;

    mArgLen = 0;
    for (int i=0; i<argc; i  ) {
        mArgLen  = strlen(argv[i])   1;
    }
    mArgLen--;

    AppRuntime runtime;
    const char* 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);

    // Parse runtime arguments.  Stop at first unrecognized option.
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    const char* parentDir = NULL;
    const char* niceName = NULL;
    const char* className = NULL;
    while (i < argc) {
        const char* arg = argv[i  ];
        if (!parentDir) {
            parentDir = arg;
        } else if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = "zygote";
        } else if (strcmp(arg, "--start-system-server") == 0) {
            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
            application = true;
        } 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) {
        runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer ? "start-system-server" : "");
    } else if (className) {
        // Remainder of args get passed to startup class main()
        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;
    }

回到 frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

它根本作了三件专门的学业:
1、调用registerZygoteSocket函数成立了一个socket接口,用来和ActivityManagerService通信;
2、调用startSystemServer函数来运转SystemServer组件;
3、调用runSelectLoopMode函数步向贰个可是循环在前方制造的socket接口上等待ActivityManagerService诉求创立新的应用程序进度。

此地invokeStaticMain的args.startClass的值为com.android.server.SystemServer。接下来SystemServer类的main函数将会被调用,笔者太灵活了~

/**
     * 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[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007",
            "--capabilities="   capabilities   ","   capabilities,
            "--runtime-init",
            "--nice-name=system_server",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
            parsedArgs = new ZygoteConnection.Arguments(args);
            ......

            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            ......
        }

        /* For child process */
        if (pid == 0) {//pid==0说明是子进程,父进程为Zygote 
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }

通过源代码的剖释清楚,其实上边根本是给二个应用程序分配贰个虚构机情状(设想机拷贝),然后经过JNI的措施去调java里有个别className类的main()方法。

总体运营框架:

1、setuid=1000,这里1000代表SYSTEM_UID,即系统经过,关于进程ID的辨证能够景仰:/frameworks/base/core/java/android/os/Process.java。
2、nice-name=system_server表示制订进度的名称叫“system_server”
3、com.android.server.SystemServer代表SystemServer类的职务。

在startSystemServer中先设置了Zygote.forkSystemServer所需的参数,然后经过forkSystemServer方法fork出SystemServer进程,末了通过handleSystemServerProcess管理新进度中的琐事。

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

在main中会加载libandroid_servers.so库,然后调用nativeInit早先化native层的Service。
ServerThread起头化一批android服务。

彩民之家论坛9066777 8

main函数的注重成效就是创办二个AppRuntime变量,然后调用它的start函数。它的定义也在一样文件app_main.cpp下面class AppRuntime : public AndroidRuntime
(AndroidRuntime的源码在/frameworks/base/core/jni下,它是空洞基类);
在AndroidRuntime.h中定义了4种运行方式

forkSystemServer最后调nativeForkSystemServer,而它是经过JNI完结,源码:/dalvik/vm/native/dalvik_system_Zygote.cpp:

init进度运行
Native服务运转
System Server, Android 服务运转
Home启动

Init进度运转

此间Zygote进度初步化完结,开头大循环了~~~
留神深入分析下第二步startSystemServer运行系统服务组件

小结一下:

static void Dalvik_dalvik_system_Zygote_forkSystemServer(
        const u4* args, JValue* pResult)
{
    pid_t pid;
    pid = forkAndSpecializeCommon(args, true);

    /* The zygote process checks whether the child process has died or not. */
    if (pid > 0) {//pid大于0,说明是在父进程中,Zygote进程往下执行
        int status;
        gDvm.systemServerPid = pid;
        /* There is a slight window that the system server process has crashed
         * but it went unnoticed because we haven't published its pid yet. So
         * we recheck here just to make sure that all is well.
         */
        if (waitpid(pid, &status, WNOHANG) == pid) {
            ALOGE("System server process %d has died. Restarting Zygote!", pid);
            kill(getpid(), SIGKILL);//一旦上面的等待返回,说明进程pid(system_server)已终止,此时Zygote杀死自己  
        }
    }
    RETURN_INT(pid);
}

//native函数注册
const DalvikNativeMethod dvm_dalvik_system_Zygote[] = {
    { "nativeFork", "()I",
      Dalvik_dalvik_system_Zygote_fork },
    { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;)I",
      Dalvik_dalvik_system_Zygote_forkAndSpecialize },
    { "nativeForkSystemServer", "(II[II[[IJJ)I",
      Dalvik_dalvik_system_Zygote_forkSystemServer },
    { NULL, NULL, NULL },
};

还记得runtime.start("com.android.internal.os.ZygoteInit", startSystemServer ? "start-system-server" : "");

接下去看一下forkSystemServer的达成:
libcore/dalvik/src/main/java/dalvik/system/Zygote.java

enum StartMode {
        Zygote,//启动Zygote
        SystemServer,//启动系统服务
        Application,//启动应用程序
        Tool,//
    };
int main(int argc, char **argv) {
    //启动uevent守护进程
    if (!strcmp(basename(argv[0]), "ueventd"))
        return ueventd_main(argc, argv);

    //启动看门狗守护进程
    if (!strcmp(basename(argv[0]), "watchdogd"))
        return watchdogd_main(argc, argv);

    umask(0);
    //创建并挂在启动所需的文件目录 
    mkdir("/dev", 0755);
    mkdir("/proc", 0755);
    mkdir("/sys", 0755);

    mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
    mkdir("/dev/pts", 0755);
    mkdir("/dev/socket", 0755);
    mount("devpts", "/dev/pts", "devpts", 0, NULL);
    mount("proc", "/proc", "proc", 0, NULL);
    mount("sysfs", "/sys", "sysfs", 0, NULL);

    close(open("/dev/.booting", O_WRONLY | O_CREAT, 0000));

    //重定向标准输入/输出/错误输出到/dev/_null_
    open_devnull_stdio();
    klog_init();//log初始化 
    property_init();//属性服务初始化  

    //从/proc/cpuinfo中读取Hardware名,在后面的mix_hwrng_into_linux_rng_action函 数中会将hardware的值设置给属性ro.hardware  
    get_hardware_name(hardware, &revision);
    //导入并设置内核变量  
    process_kernel_cmdline();
    ......
    INFO("property initn");
    if (!is_charger)
        property_load_boot_defaults();

    INFO("reading config filen");
    init_parse_config_file("/init.rc");//解析init.rc配置文件
    /* 
     * 解析完init.rc后会得到一系列的action等,下面的代码将执行处于early-init阶段的 action。 
     * init将action按照执行时间段的不同分为early-init、init、early-boot、boot。 
     * 进行这样的划分是由于有些动作之间具有依赖关系,某些动作只有在其他动作完成后才能执行,所以就有了先后的区别。 
     * 具体哪些动作属于哪个阶段是在init.rc中的配置决定的 
     */ 
    action_for_each_trigger("early-init", action_add_queue_tail);
    ......

    for(;;) {//init进入无限循环
        ......
        execute_one_command();
        restart_processes();//重启已经死去的进程 
        ...... 
        nr = poll(ufds, fd_count, timeout); //等待事件发生
        if (nr <= 0)
            continue;

        for (i = 0; i < fd_count; i  ) {
            if (ufds[i].revents == POLLIN) {
                if (ufds[i].fd == get_property_set_fd())//处理属性服务事件 
                    handle_property_set_fd();
                else if (ufds[i].fd == get_keychord_fd())//处理keychord事件
                    handle_keychord();
                else if (ufds[i].fd == get_signal_fd())
                    handle_signal();//处理SIGCHLD信号事件
            }
        }
    }

    return 0;
}

首先uboot携带Linux内核运维,然后在客商空间中运维init进度,再开发银行别的系统经过。在系统运维完毕到位后,init将改成守护进度监视系统别的进程。Android是基于Linux的操作系统,所以init也是Android系统中客户空间的首先个经过,它的历程号是1。

再看看实际的start函数做了何等

/**
     * Special method to start the system server process. In addition to the
     * common actions performed in forkAndSpecialize, the pid of the child
     * process is recorded such that the death of the child process will cause
     * zygote to exit.
     * 注意由zygote fork 出的system_service进程如果死了,则zygote进程也退出
     */
    public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
        preFork();
        int pid = nativeForkSystemServer(
                uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
        postFork();
        return pid;
    }
    native public static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);

终极将参数往下传给RuntimeInit.zygoteInit(,)
源码:frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

   /**
     * The main function called when started through the zygote process. This
     * could be unified with main(), if the native code in nativeFinishInit()
     * were rationalized with Zygote startup.
     */
    public static final void zygoteInit(int targetSdkVersion, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");

        redirectLogStreams();//将System.out 和 System.err 输出重定向到Android 的Log系统 
    /* 
     * 初始化了一些系统属性,其中最重要的一点就是设置了一个未捕捉异常的handler, 
     * 当代码有任何未知异常,就会执行它, 
     * 调试过Android代码的同学经常看到的"*** FATAL EXCEPTION IN SYSTEM PROCESS" 打印就出自这里 
     */  
        commonInit();
    /* 
     * 最终会调用app_main的onZygoteInit函数 
     * 这里的作用是在新进程中引入Binder,也就说通过nativeZygoteInit以后,新的进程就可以使用Binder进程通信了 
     */  
        nativeZygoteInit();

        applicationInit(targetSdkVersion, argv);//应用初始化
    }

   private static void applicationInit(int targetSdkVersion, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        // If the application calls System.exit(), terminate the process
        // immediately without running any shutdown hooks.  It is not possible to
        // shutdown an Android application gracefully.  Among other things, the
        // Android runtime shutdown hooks close the Binder driver, which can cause
        // leftover running threads to crash before the process actually exits.
        nativeSetExitWithoutCleanup(true);

        // We want to be fairly aggressive about heap utilization, to avoid
        // holding on to a lot of memory that isn't needed.
        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

        final Arguments args;
        try {
            args = new Arguments(argv);
        } catch (IllegalArgumentException ex) {
            Slog.e(TAG, ex.getMessage());
            // let the process exit
            return;
        }

        // Remaining arguments are passed to the start class's static main
        invokeStaticMain(args.startClass, args.startArgs);
    }
public static void main(String[] args) {

        /*
         * In case the runtime switched since last boot (such as when
         * the old runtime was removed in an OTA), set the system
         * property so that it is in sync.
         */
        SystemProperties.set("persist.sys.dalvik.vm.lib",
                             VMRuntime.getRuntime().vmLibrary());

        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {//调整时间
            Slog.w(TAG, "System clock is before 1970; setting to 1970.");
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }
         ......

        // Mmmmmm... more memory!
        dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();

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

        Environment.setUserRequired(true);

        System.loadLibrary("android_servers");

        Slog.i(TAG, "Entered the Android system server!");

        // Initialize native services.
        nativeInit();//初始化本地所以服务 > SensorService

        // This used to be its own separate thread, but now it is
        // just the loop we run on the main thread.
        ServerThread thr = new ServerThread();
        thr.initAndLoop();
    }
版权声明:本文由彩民之家高手论坛发布于编程技术,转载请注明出处:Framework基础:Android系统经过是怎么来的?彩民之家