Android启动过程--Kernel启动和init启动

本文基于Android 12介绍Linux Kernel层和init进程的启动过程。

一、Android启动过程概述

Android正常模式启动过程如下图所示:

  • 启动电源:当按下电源键时,引用芯片从预定义的地方开始执行,加载引导程序BootLoader到RAM,开始执行。
  • BootLoader:它是在操作系统内核运行之前运行的一段小程序,初始化硬件设备、建立内存空间映射图,从而将OS拉起来。
  • Linux Kernel:它启动后,设置缓存、计划列表、加载驱动,启动init进程。
  • init:初始化和启动PropertyService,启动zygote和servicemanager进程。
  • zygote:c++层:启动VM并为VM注册JNI方法,调用ZygoteInit进入Java层;Java层:预加载类、库等各种资源,创建服务器端Socket,启动systemserver进程。
  • Launcher:在SystemServer.startOtherService()中的AMS.systemReady()中启动Launcher。

二、Linux Kernel启动过程

Android 12源码中没有相关Kernel的代码,以下是参考《Android的设计与实现 卷I》和项目上kernel代码总结。

Kernel启动分为两个阶段:

(1)内核引导阶段。通常使用汇编语言,代码路径为:​kernel/msm-4.19/arch/arm/kernel/head.S和
kernel/msm-4.19/arch/arm/kernel/head-common.S。

(2)内核启动阶段。引导阶段调用start_kernel()进入启动阶段,代码路径在:/kernel/msm-4.19/init/main.c。Kernel启动init过程如下:

三、init进程启动过程

init进程是Linux Kernel用户空间的第一个进程,Pid=1。代码路径为: /system/core/init/,他的入口为main.cpp,它的main()方法会多次进入,源码参考地址为:main.cpp - OpenGrok cross reference for /system/core/init/main.cpp

1. init进程启动的FirstStageMain阶段

在FirstStageMain阶段,主要的工作如下:

  • umask(0):清除系统默认权限,保证新建目录的访问权限由mkdir设置。
  • 使用mkdir/mount/chmod指令来创建基本文件系统目录并挂载相关的文件系统。Android系统挂载了tmpfs、devpts、proc、sysfs这四类文件系统。其中,/dev是设备目录,所有外部设备和虚拟设备都在该目录下;/proc是存储当前系统内核运行信息的文件目录,/sys存储了硬件设备在内核上的映射。
  • SetStdioToDevNull():关闭/stdin/stdout/stderr的fd,重定向到/dev/null。
  • InitKernelLogging():初始化kernel日志,输出到/dev/kmsg。
  • load内核各模块。
  • 第一阶段做完后,再次调用main()进入SetupSelinux阶段。

2. init进程启动的SetupSelinux阶段

 Selinux启动完后会再次携带参数调用main()进入SecondStageMain阶段。

3. init进程启动的SecondStageMain阶段

在FirstStageMain阶段,主要的工作如下:

  • SetStdioToDevNull():关闭/stdin/stdout/stderr的fd,重定向到/dev/null。
  • InitKernelLogging():初始化kernel日志,输出到/dev/kmsg。
  • 创建会话秘钥。
  • 设置init进程和其fork()的子进程的oom_adj。oom_adj主要用在lowmemorykiller机制中,每一类别的进程会有其oom_adj的范围,oom_adj值越大表示进程越不重要,当lowmemory时,会优先kill oom_adj高的进程。
  • PropertyInit(),初始化属性服务。

初始化属性服务的逻辑:

1. mkdir "/dev/__properties"目录;

2. createSerializedPropertyInfo()读取context信息并将内容序列化写入 /dev/__properties__/ property_info;

3. ProcessKernelDt()读取设备树DT;

4. ProcessKernelCmdline()加载proc/cmdline,把"androidboot."开头的替换成ro.boot并设置新值。

5.ProcessBootconfig()加载/proc/bootconfig,把"androidboot."开头的替换成ro.boot并设置新值。

6. ExportKernelBootProps()将kernel变量传播到init可用的变量和其当前可用的属性。

7. PropertyLoadBootDefaults()加载开机默认的属性

  • StartPropertyService:启动属性服务。
  •  InitializeSubcontext:初始化SubContext。
  • 获取ActionManager实例和ServiceList实例
  • LoadBootScrpts:加载和解析init.rc文件。
  • 把Action和Trigger添加到ActionManager的相应队列中。
  • 无限循环执行init.rc中的command。

 init.rc中可以看到在触发“init”,会启动logd、servicemanager、hwservicemanager等。

on init
    sysclktz 0 //将时区设置为0
    ...
    # Start logd before any other services run to ensure we capture all of their logs.
    start logd
    # Start essential services.
    start servicemanager
    start hwservicemanager
    start vndservicemanager

触发 late-init,会启动各种fs,Zygote、early-boot、boot等。

# Mount filesystems and start core system services.
on late-ini
    trigger early-fs
    trigger fs
    trigger post-fs.
    trigger late-fs
    trigger post-fs-data
    trigger load_persist_props_action
    trigger load_bpf_programs
    #触发启动zygote
    trigger zygote-start
    trigger firmware_mounts_complete
    trigger early-boot
    trigger boot


on early-fs
    # Once metadata has been mounted, we'll need vold to deal with userdata checkpointing
    start vold

on post-fs
    exec - system system -- /system/bin/vdc checkpoint markBootAttempt
    mount rootfs rootfs / remount bind ro nodev

    # Mount default storage into root namespace
    mount none /mnt/user/0 /storage bind rec
    mount none none /storage slave rec

    chown system cache /cache
    chmod 0770 /cache
    restorecon_recursive /cache
    mkdir /cache/recovery 0770 system cache

    chown root system /proc/kmsg
    chmod 0440 /proc/kmsg

# It is recommended to put unnecessary data/ initialization from post-fs-data
# to start-zygote in device's init.rc to unblock zygote start.
on zygote-start && property:ro.crypto.state=unencrypted
    wait_for_prop odsign.verification.done 1
    # A/B update verifier that marks a successful boot.
    exec_start update_verifier_nonencrypted
    start statsd
    start netd
    start zygote
    start zygote_secondary

所以servicemanager进程比zygote启动更早。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android启动流程主要包括以下几个步骤: 1. Bootloader(引导加载程序):当我们按下 Android 设备的电源键时,系统会进入 bootloader 阶段,这个阶段主要是检测硬件设备并加载内核。 2. Kernel(内核):当 bootloader 加载完毕后,会启动内核。Android 的内核主要是 Linux 内核,它负责管理设备的硬件资源和提供基本的系统服务。 3. Init(系统初始化):在内核启动后,会运行 init 进程,它是 Android 系统的第一个用户空间进程,主要负责初始化系统环境、启动系统服务和应用程序。 4. System Server(系统服务):系统服务是 Android 系统的核心部分,它们提供了各种系统功能,例如:窗口管理、通知、电源管理等。 5. Zygote(应用程序启动):Zygote 进程是 Android 系统中的一个特殊进程,它会在系统启动启动,并且负责创建和管理所有的应用程序进程。当我们启动一个应用程序时,Zygote 会为该应用程序创建一个新的进程,并且该进程会继承 Zygote 的一些属性和状态。 6. 应用程序进程:应用程序进程是 Android 系统中运行应用程序的最小单位,每个应用程序都会运行在一个独立的进程中,它们之间相互隔离,互不干扰。 以上是 Android 系统启动的主要流程,当然在实际的启动过程中还有很多细节需要处理,例如:启动动画、初始化硬件设备等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值