android源码4.4.2----系统启动过程分析

Android系统启动过程分析

大家都知道Android系统是Linux的自由及开放源代码的操作系统,Linux系统的根进程 init ,Android系统的根进程Zygote。

Zygote进程是所有的android进程的父进程,包括SystemServer和各种应用进程都是通过Zygote进程fork出来的。Zygote(孵化)

进程相当于是android系统的根进程,后面所有的进程都是通过这个进程fork出来的,而Zygote进程则是通过Linux系统的init进程启动的,也就是说,android系统中各种进程的启动方式

init进程 –> Zygote进程 –> SystemServer进程 –>各种service进程

  • init进程:linux的根进程,android系统是基于linux系统的,因此可以算作是整个android操作系统的第一个进程;

  • Zygote进程:android系统的根进程,主要作用:可以作用Zygote进程fork出SystemServer进程和各种应用进程;

  • SystemServer进程:主要是在这个进程中启动系统的各项服务,比如ActivityManagerService,PackageManagerService,WindowManagerService服务等等;

  • 各种应用进程:启动自己编写的客户端应用时,一般都是重新启动一个应用进程,有自己的虚拟机与运行环境;


如果不清楚fork功能,fork函数详解 一定能让你有所明悟,对于后续理解Zygote进程会非常有帮助

一。init进程
path : /system/core/init/init.c
分析 main 函数,我们发现除了创建文件系统的初始化动作之外,就是解析执行 init.rc

而其中最重要的便是启动孵化器Zygote进程

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

在上面代码中,第一行配置了一个名为zygote的服务,这个服务将会运行 /system/bin/app_process,

剩余部分为app_process的传入参数(以空格分割)。


剩下的几行代码声明了此服务的选项。

class main ----说明zygote是一个类型为main的服务

socket zygote stream 660 root system ----它会创建一个socket,这个socket的类型为stream,权限为666(socket zygote stream 666)。


当重启此服务的时候,需要完成以下事情:

❶写/sys.android_power/request_state为wake


❷写/sys/power/state为on


❸重新启动media服务


❹重新启动netd服务


二。Zygote 进程启动过程

2.1 下面我们先来具体看一下 app_process

/frameworks/base/cmds/app_process/app_main.cpp

因为是可执行程序(详见 对应目录的android.mk 文件 include $(BUILD_EXECUTABLE) )所以查找编译

文件中的Main函数

int main(int argc, char* const argv[])
{

AppRuntime runtime;

//参数处理

 

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



}


最后通过 runtime.start("com.android.internal.os.ZygoteInit", startSystemServer ? "start-system-server" : "");

启动 孵化器进程,startSystemServer 作为参数传入 Zygote进程;


2.2 AndroidRuntime

位于文件frameworks/base/core/jni/ AndroidRuntime.cpp,类定义于:

    frameworks/base/include/android_runtime/AndroidRuntime.h


/*
 * 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 char* options)
{
    ALOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",
            className != NULL ? className : "(unknown)");


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


/*
     * Register android functions.
     */
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }





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


}


AndroidRuntime::start 启动一个Android运行时环境,首先启动虚拟机,然后运行 启动类中

叫“static void main(String [] args)”类中的方法,然后run

env->CallStaticVoidMethod(startClass, startMeth, strArray);


这样就可以运行起来 Zygote进程了


2.3 ZygoteInit

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

源码位于 frameworks/base/core/java/com/android/internal/os/ZygoteInit.java


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


            // Disable tracing so that forked processes do not inherit stale tracing tags from
            // Zygote.
            Trace.setTracingEnabled(false);


            // If requested, start system server directly from Zygote
            if (argv.length != 2) {
                throw new RuntimeException(argv[0] + USAGE_STRING);
            }


        if (argv[1].equals("start-system-server")) {
            startSystemServer();
        } else if (!argv[1].equals("")) {
            throw new RuntimeException(argv[0] + USAGE_STRING);
        }






        Log.i(TAG, "Accepting command socket connections");


        runSelectLoop();//主循环,起到孵化器的作用,通过 socket 消息,fork出不同的子线程


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

主要有两个功能,
首先,fork出SystemServer进程
其次,运行孵化器功能,runSelectLoop();//主循环,起到孵化器的作用,通过 socket 消息,fork出不同的子线程

三。SystemServer
文件位于 :/frameworks/base/services/java/com/android/server/SystemServer.java



public class SystemServer {
   private static final String TAG = "SystemServer";

   public static final int FACTORY_TEST_OFF = 0;
   public static final int FACTORY_TEST_LOW_LEVEL = 1;
   public static final int FACTORY_TEST_HIGH_LEVEL = 2;

   static Timer timer;
   static final long SNAPSHOT_INTERVAL = 60 * 60 * 1000; // 1hr

   // The earliest supported time.  We pick one day into 1970, to
   // give any timezone code room without going into negative time.
   private static final long EARLIEST_SUPPORTED_TIME = 86400 * 1000;

   /**
    * Called to initialize native system services.
    */
   private static native void nativeInit();

   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. We can't do this in
        * libnativehelper's JniInvocation::Init code where we already
        * had to fallback to a different runtime because it is
        * running as root and we need to be the system user to set
        * the property. http://b/11463182
        */
       SystemProperties.set("persist.sys.dalvik.vm.lib",
                            VMRuntime.getRuntime().vmLibrary());

       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, "System clock is before 1970; setting to 1970.");
           SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
       }

       if (SamplingProfilerIntegration.isEnabled()) {
           SamplingProfilerIntegration.start();
           timer = new Timer();
           timer.schedule(new TimerTask() {
               @Override
               public void run() {
                   SamplingProfilerIntegration.writeSnapshot("system_server", null);
               }
           }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
       }

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

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

1.设置运行环境库 
SystemProperties.set("persist.sys.dalvik.vm.lib",
                            VMRuntime.getRuntime().vmLibrary());
2.设置系统时间
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, "System clock is before 1970; setting to 1970.");
           SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
       }
       
3.性能统计
if (SamplingProfilerIntegration.isEnabled()) {
           SamplingProfilerIntegration.start();
           timer = new Timer();
           timer.schedule(new TimerTask() {
               @Override
               public void run() {
                   SamplingProfilerIntegration.writeSnapshot("system_server", null);
               }
           }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
       }

4.设置内存上限
// 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);
       
5.设置用户,否则无法使用环境变量
Environment.setUserRequired(true);


6.加载系统服务库
System.loadLibrary("android_servers");

7.初始化本地服务----SensorService--硬件相关
nativeInit();

static void android_server_SystemServer_nativeInit(JNIEnv* env, jobject clazz) {
   char propBuf[PROPERTY_VALUE_MAX];
   property_get("system_init.startsensorservice", propBuf, "1");
   if (strcmp(propBuf, "1") == 0) {
       // Start the sensor service
       SensorService::instantiate();
   }
}

8.系统服务线程--完成系统各种服务的启动
ServerThread thr = new ServerThread();
        thr.initAndLoop();



class ServerThread
public void initAndLoop() {



try {
            // Wait for installd to finished starting up so that it has a chance to
            // create critical directories such as /data/user with the appropriate
            // permissions.  We need this to complete before we initialize other services.
            Slog.i(TAG, "Waiting for installd to be ready.");
            installer = new Installer();
            installer.ping();


            Slog.i(TAG, "Power Manager");
            power = new PowerManagerService();
            ServiceManager.addService(Context.POWER_SERVICE, power);


            Slog.i(TAG, "Activity Manager");
            context = ActivityManagerService.main(factoryTest);
        } catch (RuntimeException e) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting bootstrap service", e);
        }
        
        
        
        
        
        
        try {
                    Slog.i(TAG, "Connectivity Service");
                    connectivity = new ConnectivityService(
                            context, networkManagement, networkStats, networkPolicy);
                    ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
                    networkStats.bindConnectivityManager(connectivity);
                    networkPolicy.bindConnectivityManager(connectivity);


                    wifiP2p.connectivityServiceReady();
                    wifi.checkAndStartWifi();
                } catch (Throwable e) {
                    reportWtf("starting Connectivity Service", e);
                }
        
        
}

1.启动context = ActivityManagerService.main(factoryTest);

2.最主要的功能--添加各种 Service
ServiceManager.addService(Context.POWER_SERVICE, power); 电源管理
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity); 链接服务






  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值