Android 系统启动

1、init进程启动

init 进程是Android系统的第一个进程,很多重要职责,例如创建Zygote和属性服务等。 init位于路劲system、core/init.

1.1引入init进程

1.启动电源以及系统启动
2.引导程序Bootloader
3.linux内核启动
4.init进程启动

1.2引入init进程

在main函数中system/core/init/init.cpp
int main(int argc, char** argv) {

//对属性服务进行初始化
property_init(); //1

//用于设置子进程信号处理函数,如果子进程(zogete进程)异常退出,init进程会调用该函数中设定的信号处理函数来处理
signal_handler_init();//2

//启动属性服务
start_property-service();//3

//解析init.rc配置文件
parser.ParseConfig(“init.rc”);//4

//重启死去的进程
restart_processes();//5
}
注释2是为了防止僵尸进程
父进程不知道子进程终止,但是此时系统进程表中还为它保留了一定的信息,子进程为僵尸进程。 进程表资源有限。

1.3init.rc

init.rc是一个配置文件,内部由Android初始化语言编写(Android Init Language)编写的脚本,它主要包含五种类型语句:
Action、Commands、Services、Options和Import。init.rc的配置代码如下所示。
system/core/rootdir/init.rc

on init
    sysclktz 0
    # Mix device-specific information into the entropy pool
    copy /proc/cmdline /dev/urandom
    copy /default.prop /dev/urandom
...

on boot
    # basic network init
    ifup lo
    hostname localhost
    domainname localdomain
    # set RLIMIT_NICE to allow priorities from 19 to -20
    setrlimit 13 40 40
...

1.4 解析Service类型语句

init.rc中的Action星语句是ActionParser来进行解析,而Service由ServiceParser来进行解析。解析service,会用到两个函数,一个是ParseSection,它会解析service的rc文件,比如上文讲到的init.zygote64.rc,ParseSection函数主要用来搭建service的架子。另一个是ParseLineSection,用于解析子项。

1.5 init启动zygote

Start方法
bool Service::Start() {
...
  pid_t pid = fork();//1.fork函数创建子进程
    if (pid == 0) {//2运行在子进程中
        umask(077);
        ...
        //3.通过execve执行程序
        if (execve(args_[0].c_str(), (char**) &strs[0], (char**) ENV) < 0) {
            ERROR("cannot execve('%s'): %s\n", args_[0].c_str(), strerror(errno));
        }

        _exit(127);
    }

走到1处,子进程还没被启动。frok创建子进程,pid=0 说明在子线程中运行。3处service子进程就会被启动,进入到service的main函数中。
frameworks/base/cmds/app_process/app_main.cpp

int main(int argc, char* const argv[])
{
  ...
  if (zygote) {
      runtime.start("com.android.internal.os.ZygoteInit", args, zygote);//1
  } 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;
  }
}

1处的代码可以得知调用runtime(AppRuntime)的start来启动zygote。

1.6 属性服务

属性服务初始化与启动

ystem/core/init/property_service.cpp

void property_init() {
    if (__system_property_area_init()) {
        ERROR("Failed to initialize property area\n");
        exit(1);
    }
}
void start_property_service() {
    property_set_fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
                                    0666, 0, 0, NULL);//1
    if (property_set_fd == -1) {
        ERROR("start_property_service socket creation failed: %s\n", strerror(errno));
        exit(1);
    }
    listen(property_set_fd, 8);//2
    register_epoll_handler(property_set_fd, handle_property_set_fd);//3
}

注释1处用来创建非阻塞的socket。注释2处调用listen函数对property_set_fd进行监听,这样创建的socket就成为了server,也就是属性服务;listen函数的第二个参数设置8意味着属性服务最多可以同时为8个试图设置属性的用户提供服务。注释3处的代码将property_set_fd放入了epoll句柄中,用epoll来监听property_set_fd:当property_set_fd中有数据到来时,init进程将用handle_property_set_fd函数进行处理。
在linux新的内核中,epoll用来替换select,epoll最大的好处在于它不会随着监听fd数目的增长而降低效率。因为内核中的select实现是采用轮询来处理的,轮询的fd数目越多,自然耗时越多。

属性服务处理请求

会调用handle_property_set_fd函数进行处理:
system/core/init/property_service.cpp

static void handle_property_set_fd()
{  
...
handler_property_set(socket,prop_value,pro_value,true);//1
}

8.0在7.0做了进一步的判断,普通属性和控制属性。

init进程总结

init进程主要做了三件事:
1.创建和挂载启动所需的文件目录
2.初始化和启动属性服务
3.解析init.rc配置文件并启动zygote进程、

2、zygote进程启动

1.Zygote简介

在Android系统中,DVM(Dalvik虚拟机)和ART、应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程来创建的,我们也将它称为孵化器。它通过fork
(复制进程)的形式来创建应用程序进程和SystemServer进程,由于Zygote进程在启动时会创建DVM或者ART,因此通过fork而创建的应用程序进程和SystemServer进程可以在内部获取一个DVM的实例拷贝。
启动流程Android 系统启动_第1张图片

2、Zygote进程总结

Zygote进程共做了如下几件事:
1.创建AppRuntime并调用其start方法,启动Zygote进程。
2.创建DVM并为DVM注册JNI.
3.通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层。
4.通过registerZygoteSocket函数创建服务端Socket,并通过runSelectLoop函数等待ActivityManagerService的请求来创建新的应用程序进程。
5.启动SystemServer进程。

3 SyetemServer进程启动过程

1.Zygote启动SyetemServer进程

Android 系统启动_第2张图片
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

           // 关闭 zygote进程创建的socket 该进程对systemserver没用
           zygoteServer.closeServerSocket();
           handleSystemServerProcess(parsedArgs);

handleSystemServerProcess函数的代码:

 ClassLoader cl = null;
          if (systemServerClasspath != null) {
              cl = createSystemServerClassLoader(systemServerClasspath,
                                                 parsedArgs.targetSdkVersion);
              Thread.currentThread().setContextClassLoader(cl);
          }
          RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);//2 

2处调用RuntimeInit的zygoteInit函数
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

 nativeZygoteInit();//1启动binder线程池
applicationInit(targetSdkVersion, argv, classLoader);//2进入systemServer的main方法

invokeStaticMain

 private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
...
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
    }

通过反射返回的cl为SystemServer类。找到SystemServer中的main函数。将找到的main函数传入到MethodAndArgsCaller异常中并抛出该异常。截获MethodAndArgsCaller异常的代码在ZygoteInit.java的main函数中
rameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {
     ...
          closeServerSocket();
      } catch (MethodAndArgsCaller caller) {
          caller.run();//1
      } catch (RuntimeException ex) {
          Log.e(TAG, "Zygote died with exception", ex);
          closeServerSocket();
          throw ex;
      }
  }

在注释1处调用了MethodAndArgsCaller的run函数:

   public void run() {
        try {
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (IllegalAccessException ex) {
         ...
        }
    }
}

2 解析SyetemServer进程

SystemServer的main函数:
frameworks/base/services/java/com/android/server/SystemServer.java

public static void main(String[] args) {
       new SystemServer().run();
   }

main函数中只调用了SystemServer的run函数,如下所示。

private void run() {
       ...
           System.loadLibrary("android_servers");//1
       ...
           mSystemServiceManager = new SystemServiceManager(mSystemContext);//2
           LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
       ...    
        try {
           Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
           startBootstrapServices();//3
           startCoreServices();//4
           startOtherServices();//5
       } catch (Throwable ex) {
           Slog.e("System", "******************************************");
           Slog.e("System", "************ Failure starting system services", ex);
           throw ex;
       } finally {
           Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
       }
       ...
   }

3.总结SyetemServer进程

SyetemServer在启动时做了如下工作:
1.启动Binder线程池,这样就可以与其他进程进行通信。
2.创建SystemServiceManager用于对系统的服务进行创建、启动和生命周期管理。
3.启动各种系统服务。

4 Launcher启动过程与系统启动流程

1.Launcher概述

launcher通俗的就是Android的系统的桌面。作用:
1、作为Android系统的启动器,用于启动应用程序
2、作为系统的桌面,用于显示和管理应用程序的快捷图标或者其他桌面组件

2.Launcher启动流程

Android 系统启动_第3张图片
在systemServer 中startOtherServices函数,会调用ActivityManagerService的systemReady函数。
systemReady函数中调用了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked函数:

3.Launcher中应用图标显示流程

Launcher的onCreate函数如下所示。
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

      @Override
    protected void onCreate(Bundle savedInstanceState) {
       ...
        LauncherAppState app = LauncherAppState.getInstance();//1 获取实例
        mDeviceProfile = getResources().getConfiguration().orientation
                == Configuration.ORIENTATION_LANDSCAPE ?
                app.getInvariantDeviceProfile().landscapeProfile
                : app.getInvariantDeviceProfile().portraitProfile;

        mSharedPrefs = Utilities.getPrefs(this);
        mIsSafeModeEnabled = getPackageManager().isSafeMode();
        mModel = app.setLauncher(this);//2
        ....
        if (!mRestoring) {
            if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {
                mModel.startLoader(PagedView.INVALID_RESTORE_PAGE);//3
            } else {
                mModel.startLoader(mWorkspace.getRestorePage());
            }
        }
...
    }

setluncher 处会调用LauncherModel的initialize函数:
在initialize函数中会将Callbacks,也就是传入的Launcher 封装成一个弱引用对象。因此我们得知mCallbacks变量指的就是封装成弱引用对象的Launcher,这个mCallbacks后文会用到它。
再回到Launcher的onCreate函数,在注释2处调用了LauncherModel的startLoader函数…

5.Android系统启动流程

1.启动电源以及系统启动
当电源按下时引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序Bootloader到RAM,然后执行。
2.引导程序BootLoader
引导程序BootLoader是在Android操作系统开始运行前的一个小程序,它的主要作用是把系统OS拉起来并运行。
3.Linux内核启动
内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。当内核完成系统设置,它首先在系统文件中寻找init.rc文件,并启动init进程。
4.init进程启动
初始化和启动属性服务,并且启动Zygote进程。
5.Zygote进程启动
创建JavaVM并为JavaVM注册JNI,创建服务端Socket,启动SystemServer进程。
6.SystemServer进程启动
启动Binder线程池和SystemServiceManager,并且启动各种系统服务。
7.Launcher启动
被SystemServer进程启动的ActivityManagerService会启动Launcher,Launcher启动后会将已安装应用的快捷图标显示到界面上。
Android 系统启动_第4张图片

你可能感兴趣的:(学习资料)