Android系统启动流程分析

这篇具有很好参考价值的文章主要介绍了Android系统启动流程分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

       当按下Android系统的开机电源按键时候,硬件会触发引导芯片,执行预定义的代码,然后加载引导程序(BootLoader)到RAM,Bootloader是Android系统起来前第一个程序,主要用来拉起Android系统程序,Android系统被拉起首先肯定会启动Linux内核。

备注: 我们再刷机时候,经常看到工具软件会让我们切换bootloader/loader模式,其实就是重新激活bootloader程序,然后再拷贝新的镜像文件重新刷机,就是通过这个程序重新初始化硬件设备,建立内存空间映射。

        我们也知道一个系统肯定会存在一些重要服务和进程来支持整个系统正常运作。  那么Android系统中肯定也存在这种重要进程,如下:  

序号 进程名称 概述
1 init进程 Linux系统中用户空间第一个进程
2 zygote进程 所有App进程的父进程,Zygote Init 
3 system_server进程 各大系统服务的载体,forkSystemServer / SystemServer
4 servicemanager进程 binder服务的大管家,守护进程循环运行在binder_loop 

内核启动首先会第一个创建init进程,进程号是1,是所有用户空间的鼻祖,init进程又会启动servicemanager(binder服务管家) 和zygote进程(Java进程鼻祖),zygote进程会创建system_server进程以及各种app进程,大致启动关系如下: 

Android系统启动流程分析,Android开发,android

源码分析:基于 android10 

inity源码分析

/system/core/init/main.cpp  

 int main(int argc, char** argv) {
  #if __has_feature(address_sanitizer)
      __asan_set_error_report_callback(AsanReportCallback);
  #endif
  
      if (!strcmp(basename(argv[0]), "ueventd")) {
          return ueventd_main(argc, argv);
      }
  
      if (argc > 1) {
          if (!strcmp(argv[1], "subcontext")) {
              android::base::InitLogging(argv, &android::base::KernelLogger);
              const BuiltinFunctionMap function_map;
  
              return SubcontextMain(argc, argv, &function_map);
          }
  
          if (!strcmp(argv[1], "selinux_setup")) {
              return SetupSelinux(argv);
          }
  
          if (!strcmp(argv[1], "second_stage")) {
              return SecondStageMain(argc, argv);
          }
      }
  
      return FirstStageMain(argc, argv);
  }

main函数有四个参数入口: 

1.参数有ueventd进入 uevent_main  

2. 参数中有subcontext,进入InitLogging和 SubcontextMain 

3. 参数中有selinux_setup,进入SetupSelinux 

4. 参数中有second_state,进入SecondStageMain 

执行顺序如下: 首先会进入FirstStateMain ,主要执行是初始化环境变量,挂载和创建基本的文件系统,并设置访问权限,挂载system、cache、data等系统分区 。 之后进入  SetupSelinxu 根据源码我们可以看到FirstStateMain最后传送了参数selinux_setup 

int FirstStageMain(int argc, char** argv) {
     
      .......  

      const char* path = "/system/bin/init";
      const char* args[] = {path, "selinux_setup", nullptr};
      execv(path, const_cast<char**>(args));
  
      // execv() only returns if an error happened, in which case we
      // panic and never fall through this conditional.
      PLOG(FATAL) << "execv(\"" << path << "\") failed";
  
      return 1;
 }

SetupSelinux主要工作谁设置SELinux安全策略,之后进入SecondStageMain 。  

int SecondStageMain(int argc, char** argv) {
        ..... 

      // oom_scroe_adj 为-1000时候相当与关闭OOM机制。 范围 -1000 - 1000 
      if (auto result = WriteFile("/proc/1/oom_score_adj", "-1000"); !result) {
          LOG(ERROR) << "Unable to write -1000 to /proc/1/oom_score_adj: " << result.error();
      }
  
      // 启用全局Seccomp 
      GlobalSeccomp();
 
      // 设置所有进程都可以访问的会话密钥环
       keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 1);
  
      // 标记booting中 
      close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
  
         //初始化属性服务,指定文件读取属性
      property_init();

      ....... 
 
      // 为第二阶段设置 SELinux。
      SelinuxSetupKernelLogging();
      SelabelInitialize();
      SelinuxRestoreContext();
  
      // android封装好的Epoll开始初始化 
      Epoll epoll;
      if (auto result = epoll.Open(); !result) {
          PLOG(FATAL) << result.error();
      }
  
     // 注册singelfd信号,为创建handler处理子进程终止信号 
      InstallSignalFdHandler(&epoll);
  

      .....  

     // 注册property_set_fd, 设置其他系统属性并开启系统属性服务   
      StartPropertyService(&epoll);
      MountHandler mount_handler(&epoll);
   
     ....... 
  
  
      ActionManager& am = ActionManager::GetInstance();
      ServiceList& sm = ServiceList::GetInstance();
     //解析init.rc 等文件,建立rc文件的action,service,启动其他进程。 
      LoadBootScripts(am, sm);
  
      
      ..... 

      am.QueueBuiltinAction(SetupCgroupsAction, "SetupCgroups");
  
      //rc文件中触发器为 on earyly-init 语句 
      am.QueueEventTrigger("early-init");
  
      // 等待冷插拔设备初始化完成 
    am.QueueBuiltinAction(wait_for_coldboot_done_action,"wait_for_coldboot_done");
      // so that we can start queuing up actions that require stuff from /dev.
      am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");
      am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits");
      am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict");

         // 设备组合键初始化操作 
      Keychords keychords;
      am.QueueBuiltinAction(
          [&epoll, &keychords](const BuiltinArguments& args) -> Result<Success> {
              for (const auto& svc : ServiceList::GetInstance()) {
                  keychords.Register(svc->keycodes());
              }
              keychords.Start(&epoll, HandleKeychord);
              return Success();
          },
          "KeychordInit");
      am.QueueBuiltinAction(console_init_action, "console_init");
  
      // 开始触发rc文件中为  on init 的语句  
      am.QueueEventTrigger("init");
  
      // Starting the BoringSSL self test, for NIAP certification compliance.
      am.QueueBuiltinAction(StartBoringSslSelfTest, "StartBoringSslSelfTest");
  
      // Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random
      // wasn't ready immediately after wait_for_coldboot_done
      am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");
  
      // Initialize binder before bringing up other system services
      am.QueueBuiltinAction(InitBinder, "InitBinder");
  
      //不要在充电器模式下挂载文件系统或启动核心系统服务。.
      std::string bootmode = GetProperty("ro.bootmode", "");
      if (bootmode == "charger") {
          am.QueueEventTrigger("charger");
      } else {
          am.QueueEventTrigger("late-init");
      }   
     // 根据属性的当前状态运行所有属性触发器。.
      am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");
  
      while (true) {
          //进入死循环s.
          auto epoll_timeout = std::optional<std::chrono::milliseconds>{};
  
          if (do_shutdown && !shutting_down) {
              do_shutdown = false;
              if (HandlePowerctlMessage(shutdown_command)) {
                  shutting_down = true;
              }
          }
  
          if (!(waiting_for_prop || Service::is_exec_service_running())) {
              am.ExecuteOneCommand();
          }
          if (!(waiting_for_prop || Service::is_exec_service_running())) {
              if (!shutting_down) {
                  auto next_process_action_time = HandleProcessActions();
 
                 // 如果有一个进程需要重新启动,请及时唤醒。
                 if (next_process_action_time) {
                     epoll_timeout = std::chrono::ceil<std::chrono::milliseconds>(
                              *next_process_action_time - boot_clock::now());
                      if (*epoll_timeout < 0ms) epoll_timeout = 0ms;
                  }
             }
  
              // 如果还有更多工作要做,请立即醒来。
              if (am.HasMoreCommands()) epoll_timeout = 0ms;
         }
  
          // 这里一直等待循环事件 过来
          if (auto result = epoll.Wait(epoll_timeout); !result) {
             LOG(ERROR) << result.error();
         }
     }
  
     return 0;
 }

其中最关键就是解析init.rc 文件,并且按照rc文件定义去启动服务,然后开启死循环,用于接受epoll事件  

init.rc文件

init.rc文件在 /system/core/rootdir/init.rc 

 import /init.environ.rc
 import /init.usb.rc
 import /init.${ro.hardware}.rc
 import /vendor/etc/init/hw/init.${ro.hardware}.rc
 import /init.usb.configfs.rc
 import /init.${ro.zygote}.rc

zygote服务启动

Zygote是由init进程通过解析init.zygote.rc文件而创建

我们可以看到/system/core/rootdir/下有4个init.zygote.rc文件,通过ro.zygote配置得值去读取对应配置文件,这里以init.zygote64.rc  为例子 


 service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
     class main
     priority -20
     user root
     group root readproc reserved_disk
     socket zygote stream 660 root system
     socket usap_pool_primary 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
     onrestart restart wificond
     writepid /dev/cpuset/foreground/tasks

对应的可执行程序是app_process64 , 对应的源文件是/frameworks/base/cmds/app_process/app_main.cpp

zygote启动过程如下: 

1.创建了AppRuntime,并且调用了start方法。 

2. AndroidRuntime调用了startVm创建了虚拟机,调用startReg注册JNI函数。 

3.通过JNI调用ZygoteInit.main 进入Java  。

4. 建立socket通道,zygote作为通讯服务端,用于响应客户端请求。 

5. 预加载通用类,drawable,color资源,共享库等,用于提高app启动效率。 

6. forksytem_server进程,上层java framework的运行载体。 

参考文章:Android系统启动-zygote篇 - Gityuan博客 | 袁辉辉的技术博客袁辉辉, Gityuan, Android博客, Android源码, Flutter博客,Flutter源码http://gityuan.com/2016/02/13/android-zygote/文章来源地址https://www.toymoban.com/news/detail-551428.html

到了这里,关于Android系统启动流程分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • android framework之Applicataion启动流程分析

    Application启动流程框架分析 启动方式一:通过Launcher启动app 启动方式二:在某一个app里启动第二个app的Activity. 以上两种方式均可触发app进程的启动。但无论哪种方式,最终通过通过调用AMS的startActivity()来启动application的。    根据上图分析, 要启动一个Application,需要涉及五

    2024年02月11日
    浏览(35)
  • Android系统启动流程概览

    Boot Rom —— Bootloader —— Linux Kernel —— init进程 —— Zygote进程(dalvik/ art)—— systemServer —— Apps init 进程是Linux系统中,用户空间启动的第一个进程。 创建并挂载一些文件目录 启动属性服务 解析 init.rc 配置文件,启动 Zygote 进程 挂载 seLinux 文件目录,创建seLinux,加载

    2024年02月06日
    浏览(34)
  • 笔记:Android 9系统启动流程

    当电源键按下时,引导芯片代码(汇编指令)会从预定的地方(固化在ROM)开始执行,将引导程序 BootLoader 加载到 RAM中,然后执行 BootLoader 是在 Android 操作系统开始前的一个小程序,主要作用是把系统OS拉起来并运行 位置: bootablebootloader 当 Linux系统被 BootLoader 程序拉起,

    2024年02月14日
    浏览(27)
  • Android系统启动流程 源码解析

    本文链接:https://blog.csdn.net/feather_wch/article/details/132518105 有道云脑图:https://note.youdao.com/s/GZ9d8vzO 1、整体流程 Boot Room BootLoader idle kthread init init ServiceManager zygote zygote SystemServer app 1、kernel/common/init/main.c 2、andorid.mk-android.bp编译 3、init是用户空间鼻祖 属于C、C++ Framework 1.1 启动源

    2024年02月11日
    浏览(31)
  • Android T 远程动画显示流程其二——系统侧动画启动流程

    接着上篇文章分析 Android T 远程动画显示流程其一 下面,我们以从桌面点击一个应用启动的场景来分析远程动画的流程,窗口添加的流程见Android T WMS窗口相关流程 这里我们从AppTransitionController.handleAppTransitionReady方法开始跟踪代码流程 代码路径:framework/services/core/java/com/and

    2024年03月28日
    浏览(32)
  • Android 12系统源码_窗口管理(一)WindowManagerService的启动流程

    WindowManagerService是Android系统中重要的服务,它是WindowManager的管理者,WindowManagerService无论对于应用开发还是Framework开发都是重要的知识点,究其原因是因为WindowManagerService有很多职责,每个职责都会涉及重要且复杂的系统,这使得WindowManagerService就像一个十字路口的交通灯一样

    2024年02月11日
    浏览(32)
  • Android9.0 系统Framework发送通知流程分析

      在android 9.0的系统rom定制化开发中,在systemui中一个重要的内容就是系统通知的展示,在状态栏展示系统发送通知的图标,而在 系统下拉通知栏中展示接收到的系统发送过来的通知,所以说对系统framework中发送通知的流程分析很重要,接下来就来分析下系统 通知从framework到

    2024年02月02日
    浏览(30)
  • Android Activity的启动流程(Android-10)

    在Android开发中,我们经常会用到startActivity(Intent)方法,但是你知道startActivity(Intent)后Activity的启动流程吗?今天就专门讲一下最基础的startActivity(Intent)看一下Activity的启动流程,同时由于Launcher的启动后续和这里基本类似,就记录在一起。注意本章都是基于Android-10来讲解的。

    2024年01月17日
    浏览(37)
  • android源码学习- APP启动流程(android12源码)

    百度一搜能找到很多讲APP启动流程的,但是往往要么就是太老旧(还是基于android6去分析的),要么就是不全(往往只讲了整个流程的一小部分)。所以我结合网上现有的文章,以及源码的阅读和调试,耗费了3整天的时间,力求写出一篇最完整,最详细,最通俗易懂的文章,

    2024年02月11日
    浏览(36)
  • Android启动流程优化 中篇

    本文链接:https://blog.csdn.net/feather_wch/article/details/131587046 1、我们可以优化部分 Application构建到主界面onWindowFocusChanged 2、启动方式(官方) 冷启动 热启动 温启动 3、怎么样算是卡顿? 卡顿:2-5-8原则 2秒以内:流程 2-5秒:可以接受 5-8秒:有些卡顿 8秒以上:非常卡顿,没办法接

    2024年02月12日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包