init进程源码分析

本文详细介绍了Android系统的启动流程,重点分析了init进程的初始化、解析启动脚本init.rc、信号处理等方面,阐述了init如何启动守护进程、Zygote、ServiceManager等关键组件,并探讨了SIGCHLD信号的处理机制,确保系统正常运行。
摘要由CSDN通过智能技术生成

1, 概述

Android系统启动流程图如下,


1,Bootloader引导

  当手机按下电源键时,最先运行的就是bootloader。主要作用是初始化基本的硬件环境(如CPU,内存,Flash等),为装载Linux内核准备合适的运行环境。一旦Linux内核装载完毕,bootloader将会从内存中清除掉。

  Fastboot 是android设计的一套通过USB更新手机分区映像的协议,方便开发人员快速更新指定的手机分区。

  Recovery 是android特有的升级系统。手机可以进行恢复出厂设置或者执行OTA,补丁和固件升级等操作。

2,Linux内核

  Android的boot.img存放的就是Linux内核和一个跟文件系统。Bootloader会把boot.img映像装进内存,然后Linux内核会执行整个系统的初始化,完成后装载跟文件系统,最后启动init进程。

3,init进程

  Init进程是android系统的第一个用户空间进程,它的进程号为1.主要作用如下,

 A,启动android系统中重要的守护进程(USB守护进程,adb,vold,rild等守护进程)

B,启动Zygote进程,会创建Dalivik虚拟机,创建SystemServer进程,响应应用程序的请求。

C,启动ServiceManager,主要用于管理Binder服务,负责Binder服务的注册和查找。

2 init进程的初始化

Init进程的源码位于/system/core/init/下,程序的入口函数main()位于文件init.cpp中。

int main(int argc, char** argv) {
    if (!strcmp(basename(argv[0]), "ueventd")) {
        return ueventd_main(argc, argv); // 执行守护进程ueventd的主函数
    }

    if (!strcmp(basename(argv[0]), "watchdogd")) {
        return watchdogd_main(argc, argv); // 执行看门狗守护进程的主函数
    }
umask(0); // 参数为0表示进程创建的文件属性是0777

Init进程代码里包含了另外2个守护进程的代码.

Android.mk文件的部分如下,

# Create symlinks
LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \
    ln -sf ../init $(TARGET_ROOT_OUT)/sbin/ueventd; \
ln -sf ../init $(TARGET_ROOT_OUT)/sbin/watchdog


if (is_first_stage) { // 挂载/创建文件
        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);
    }  
selinux_initialize(is_first_stage); // 初始化SELinux

 init_parse_config_file("/init.rc"); // 解析 init.rc 文件

    action_for_each_trigger("early-init", action_add_queue_tail);
    // 将指定的action加入到action_queue 中
    // Queue an action that waits for coldboot done so we know ueventd has set up all of /dev...
    queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");
    // ... so that we can start queuing up actions that require stuff from /dev.
    queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
    queue_builtin_action(keychord_init_action, "keychord_init");
    queue_builtin_action(console_init_action, "console_init");
    •••


while (true) {
        if (!waiting_for_exec) {
            execute_one_command();
            restart_processes(); // 启动服务进程
        }

3 解析启动脚本init.rc

3.1init.rc文件介绍

Init.rc脚本使用的是一种初始化语言,其中包含了4类声明:

1)Action

2)Command

3)Service

4)Option

该语言规定,Action和Service是以一种“小节”(Section)的形式出现的,其中每个Action小节可以含有若干Command,而每个Service小节可以含有若干Option。小节只有起始标记,却没有明确的结束标记,也就是说,是用“后一个小节”的起始来结束“前一个小节”的。

 

脚本中的Action大体上表示一个“行动”,它用一系列Command共同完成该“行动”。Action需要有一个触发器(trigger)来触发它,一旦满足了触发条件,这个Action就会被加到执行队列的末尾。Action的形式如下:

on  <trigger> // trigger 是触发器
 <command1>  // 命令
 <command2>

例如,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值