Android init 进程流程分析 一

news2025/7/19 15:07:59

init 进程流程分析 一

  • 1.1引入init进程
  • 1.2 init 进程入口函数
  • 参考博客
  • 预告
    • 下一章 FirstStageMain()分析

1.1引入init进程

1.启动电源以及系统启动:
上电引导芯片从预定义的地放(固化在ROM)开始执行,加载引导程序Bootloader 到RAM中,然后执行。
注释:1、仅读存储器 (Read-Only Memory,ROM) 2、随机存取存储器 (Random Access Memory,RAM)
在这里插入图片描述
2.引导程序Bootloader:
负责将系统拉起来并运行
在这里插入图片描述
3.linux内核启动
在这里插入图片描述
当内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。此外,还启动了Kernel的swapper进程(pid = 0)和kthreadd进程(pid = 2)。下面分别介绍下它们:

1.swapper进程:又称为idle进程,系统初始化过程Kernel由无到有开创的第一个进程, 用于初始化进程管理、内存管理,加载Binder Driver、Display、Camera Driver等相关工作。

2.kthreadd进程:Linux系统的内核进程,是所有内核进程的鼻祖,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等内核守护进程。

在这里插入图片描述
kernel_init 主要工作是完成一些 init 的初始化操作,然后去系统根目录下依次找 ramdisk_execute_command 和 execute_command 设置的应用程序,如果这两个目录都找不到,就依次去根目录下找 /sbin/init,/etc/init,/bin/init,/bin/sh 这四个应用程序进行启动,只要这些应用程序有一个启动了,其他就不启动了.Android 系统一般会在根目录下放一个 init 的可执行文件,也就是说 Linux 系统的 init 进程在内核初始化完成后,就直接通过 run_init_process 函数执行 init 这个文件,该可执行文件的源代码在 system/core/init/main.cpp 中。

在内核完成系统设置后,它首先在系统文件中寻找 init.rc 文件,井启动 init 进程。
在这里插入图片描述

1.2 init 进程入口函数

init进程是Android启动过程中在Linux系统中用户空间的第一个进程。
init启动入口是在/system/core/init/init.cpp文件的SecondStageMain方法中,但调用init的SecondStageMain方法是在/system/core/init/main.cpp中的main方法进行的,所以先从/system/core/init/main.cpp的main方法开始。
因此我们先分析第一阶段。

路径:/system/core/init/main.cpp
/*
 * 1.第一个参数argc表示参数个数,第二个参数是参数列表,也就是具体的参数
 * 2.main函数有四个参数入口,
 *一是参数中有ueventd,进入ueventd_main
 *二是参数中有subcontext,进入InitLogging 和SubcontextMain
 *三是参数中有selinux_setup,进入SetupSelinux
 *四是参数中有second_stage,进入SecondStageMain
 *3.main的执行顺序如下:
   *  (1)ueventd_main    init进程创建子进程ueventd,
   *      并将创建设备节点文件的工作托付给ueventd,ueventd通过两种方式创建设备节点文件
   *  (2)FirstStageMain  启动第一阶段
   *  (3)SetupSelinux     加载selinux规则,并设置selinux日志,完成SELinux相关工作
   *  (4)SecondStageMain  启动第二阶段
 */
int main(int argc, char** argv) {
#if __has_feature(address_sanitizer)
    __asan_set_error_report_callback(AsanReportCallback);
#endif  
// __has_feature 大致的意思是通过给定的值,判断编译器是否支持该特性
// address_sanitizer 检测内存访问错误的工具
//条件编译 判断 内存检测工具 当内存检测工具为TRUE,则走下面的回调函数。

    setpriority(PRIO_PROCESS, 0, -20);
    // int setpriority(int which, int who, int prio)方法可以用来设置进程、进程组和用户的进程执行优先权,故which有三个参数可选:PRIO_PROCESS,PRIO_PGRP,PRIO_USER
    // 参数PRIO_PROCESS表示对进程设置优先级,0表示进程识别码,-20表示最高优先级(优先级在-20~20之间,越小越优先,默认为0,必须拥有root权限才能设置为低于0的数值)
    // Boost prio which will be restored later
    
    if (!strcmp(basename(argv[0]), "ueventd")) {
      // 1.创建设备节点,权限设定等,当argv[0]的内容为ueventd时,strcmp()函数的值为0,再使用!strcmp进行取反,则0变为1,1就是true。
      //strcmp比较字符串函数
        return ueventd_main(argc, argv);
        //重点2:ueventd_main:创建设备节点,权限设定等
    }
      
    // 当传入的参数个数大于1时,执行下面的几个操作:
    if (argc > 1) {
        // 参数为“subcontext”时,初始化日志系统
        if (!strcmp(argv[1], "subcontext")) {
            android::base::InitLogging(argv, &android::base::KernelLogger);
            const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();
            return SubcontextMain(argc, argv, &function_map);
        }
          
        // 3. 参数为“selinux_setup”,启动Selinux安全策略
        if (!strcmp(argv[1], "selinux_setup")) {
            return SetupSelinux(argv);
            //重点3. SetupSelinux:启动Selinux安全策略
        }
          
        // 4. 参数为“second_stage”,启动init进程第二阶段:解析init.rc文件,提供属性服务,创建epoll与处理子进程的终止等
        if (!strcmp(argv[1], "second_stage")) {
            return SecondStageMain(argc, argv);
          //重点4. SecondStageMain:解析init.rc文件,提供属性服务,创建epoll与处理子进程的终止等  
        }
    }
  
    // 2. 默认启动init进程第一阶段:挂载相关文件系统等
    return FirstStageMain(argc, argv);
   //重点 1. FirstStageMain:挂载相关文件系统等
}

注释:由kernel_init()中run_init_process(ramdisk_execute_command)启动init进程。(ramdisk_execute_command值为/init)
注释:这个可执行的init就是man.cpp编译出来的,第一次启动的时候是没有参数的,所以会走'重点1'也就是init第一阶段

在 Android 系统启动时,进程启动的顺序如下:

1、内核启动后,执行 init 进程。

2、init 进程调用 FirstStageMain() 函数,该函数主要是设置一些系统属性(例如设置安卓运行时的文件夹位置、开启 adb 调试等)。

3、FirstStageMain() 函数调用 SecondStageMain() 函数。

4、SecondStageMain() 函数主要是启动 ueventd 进程。

5、ueventd 进程启动后,会执行 ueventd_main() 函数。

6、ueventd_main() 函数主要是监控系统中硬件设备的插拔事件并向系统发送事件消息。

7、SecondStageMain() 函数会继续执行,调用 SetupSelinux() 函数,该函数主要是启动 selinux 安全模块,进行安全策略的加载和管理。

8、SetupSelinux() 函数执行完成后,init 进程就进入了等待状态,等待系统其他进程的启动和处理。

因此,进程的启动顺序是 FirstStageMain() -> SecondStageMain() -> ueventd_main() -> SetupSelinux()。

参考博客

kernel init
参考其第二部分
Address Sanitizer
因此,Google 开发了一款专门用于检测内存访问错误的工具:AddressSanitizer(简称 ASan),它可以自动检测程序运行时(runtime)发生的许多内存访问错误。
setpriority
函数说明:setpriority()可用来设置进程、进程组和用户的进程执行优先权。参数which 有三种数值, 参数who 则依which 值有不同定义。
basename
basename命令用于获取路径中的文件名或路径名,还可以对末尾字符进行删除。
ueventd
Android 中的 ueventd 是一个守护进程,它通过netlink scoket监听内核生成的uevent消息,当ueventd收到这样的消息时,它通过采取适当的行动来处理它,通常是在/dev中创建设备节点,设置文件权限,设置selinux标签等。ueventd还可以处理内核请求的固件加载、创建块设备符号链接以及创建字符设备。

预告

下一章 FirstStageMain()分析

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/369462.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

格雷码的实现

格雷码:任意两个相邻的二进制数之间只有一位不同 想必通信专业的学生应该都接触过格雷码,它出现在数电、通信原理等课程里。 如下图所示一个四位格雷码是什么样子的: 格雷码的特点: 其最大的特点是任意上下相邻的两个码值间&am…

css学习-----web

引入方式 内嵌式 css写在style标签中 外链式 css写在一个单独的.css文件中 <link rel"stylesheet" href"./文件名.css">stylesheet关系为样式表&#xff1b; href地址 行內式 css写在标签的style属性中 可以配合js使用 选择器 标签选择器是选…

CTFer成长之路之XSS的魔力

XSS的魔力CTF XSS闯关 题目描述: 你能否过关斩将解决所有XSS问题最终获得flag呢&#xff1f; docker-compose.yml version: "3.2"services:xss:image: registry.cn-hangzhou.aliyuncs.com/n1book/web-xss:latestports:- 3000:3000启动方式 docker-compose up -…

Spring依赖注入(四):Bean的循环依赖是如何产生和解决的?

前言其实这篇文章才是正主&#xff0c;前面几篇文章&#xff1a;Spring依赖注入&#xff08;一&#xff09;&#xff1a;字段注入的方式是如何工作的&#xff1f;Sprng依赖注入&#xff08;二&#xff09;&#xff1a;setter注入是如何工作的&#xff1f;Sprng依赖注入&#xf…

easyExcel与poi版本不兼容导致的后台报错问题

1、背景&#xff1a;最新接手公司系统excel导入解析模块&#xff0c;点击批量导入&#xff0c;后台报错如下 com.alibaba.excel.exception.ExcelAnalysisException: java.lang.NoClassDefFoundError: org/apache/poi/poifs/filesystem/FileMagicat com.alibaba.excel.analysis.…

CycleGAN代码使用入门

以下内容为本人亲测使用过程&#xff0c;完成了橘子到苹果的AI转化效果&#xff0c;先上效果&#xff1a; 1、下载数据集 Index of /cyclegan/datasets 本次做的是苹果和橘子相互转化的实验&#xff0c;所以下载apple2orange.zip数据集 2、下载代码 github地址为&#xff1a;…

ChatGPT从下游应用“火”到了上游芯片厂,国内谁将受益?

因库存陷入低迷周期的半导体市场近日因ChatGPT的火热而重新受到外界关注。 原文链接&#xff1a;ChatGPT从下游应用“火”到了上游芯片厂&#xff0c;国内谁将受益&#xff1f; 由于ChatGPT属于生成式AI&#xff0c;被誉为“AI芯片”第一股的英伟达应声而涨。2月13日收盘&#…

Go高质量编程与性能调优-学习笔记

1 高质量编程 1.1 简介 1.1.1 高质量代码 高质量代码即正确可靠、简洁清晰的代码 1.1.2 编程原则 简单性可读性生产力1.2 编码规范 1.2.1 代码格式 推荐gofmt自动格式化代码&#xff01; 推荐goimports实现gofmt依赖包管理&#xff01; 1.2.2 注释 注释要解释代码作用、…

5个设计师常用素材库

推荐5个设计素材网站&#xff0c;免费下载&#xff01; 1、菜鸟图库 菜鸟图库-免费设计素材下载 菜鸟图库是一个素材量非常丰富的网站&#xff0c;该网站聚合了平面、UI、淘宝电商、高清背景图、图片、插画等高质量素材。平面设计模板非常多&#xff0c;很多都能免费下载&…

springmvc实现controller接口

springmvc实现controller接口 前置配置 基础环境 springmvc 环境 jdk1.8 tomcat8.5 集成环境 ideasmart-tomcat (idea 中 tomcat插件) 实现controller接口 import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Control…

UNIAPP实战项目笔记59 NodeJS后端生成token 和 修复一些bug

UNIAPP实战项目笔记59 NodeJS后端生成token 和 修复一些bug 后端保持数据时往数据库写入token 修复一些前面遗留的问题bug 实际案例图片 后端接口文件 index.js var express require(express); var router express.Router(); var connection require(../db/sql.js); var us…

11、STM32通用定时器输出PWM

目录 1.通用定时器输出PWM 2.PWM的工作原理 3.PWM的内部运作机制 4.PWM的模式 41.边沿对齐模式 5.自动加载的预加载寄存器 6.定时器输出PWM结构体讲解 7.定时器输出PWM库函数讲解 8.定时器输出PWM----实战驱动SG90舵机 1.通用定时器输出PWM 以TIM3为例&#xff0c;STM…

makdown模版参考

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…

一次性打包学透 Spring

不知从何时开始&#xff0c;Spring 这个词开始频繁地出现在 Java 服务端开发者的日常工作中&#xff0c;很多 Java 开发者从工作的第一天开始就在使用 Spring Framework&#xff0c;甚至有人调侃“不会 Spring 都不好意思自称是个 Java 开发者”。 之所以出现这种局面&#xf…

危害肠道健康的两大敌人:诺如病毒和轮状病毒

谷禾健康 // 近日&#xff0c;多地发生诺如病毒感染事件&#xff0c;诺如病毒引起的急性感染性腹泻进入发病高峰期。那么什么是诺如病毒&#xff1f;我们又该如何预防&#xff1f; 诺如病毒和轮状病毒都是传染性很强的肠道病毒&#xff0c;是导致急性胃肠炎的最重要原因之一。会…

如何自己搭建一个ai画图系统? 从0开始云服务器部署novelai

如何自己搭建一个ai画图系统&#xff1f; 从0开始云服务器部署novelai ​ 上面两张图都是通过ai生成的&#xff0c;是不是有以假乱真的感觉。 本教程提供的是自己搭建一个可以外网访问的ai系统的方法&#xff0c;需要采购gpu服务器&#xff08;后续会出白嫖的方式&#xff09;&…

Java俄罗斯方块游戏

技术&#xff1a;Java等摘要&#xff1a;俄罗斯方块是一款十分经典的游戏&#xff0c;它的主要运行规律为对系统随机产生的图形进行上下左右移动、旋转等操纵&#xff0c;使之排列成完整的一行或多行并且消除得分。它上手容易&#xff0c;难度循序渐进&#xff0c;老少皆宜&…

Android 架构 MVC MVP MVVM,这一波你应该了然于心

MVC&#xff0c;MVP和MVVM是软件比较常用的三种软件架构&#xff0c;这三种架构的目的都是分离&#xff0c;避免将过多的逻辑全部堆积在一个类中。在Android中&#xff0c;Activity中既有UI的相关处理逻辑&#xff0c;又有数据获取逻辑&#xff0c;从而导致Activity逻辑复杂不单…

Android入门第66天-使用AOP

开篇这篇恐怕又是一篇补足网上超9成关于这个领域实际都是错的、用不起来的一个知识点了。网上太多太多教程和案例用的是一个叫hujiang的AOP组件-com.hujiang.aspectjx:gradle-android-plugin-aspectjx。首先这些错的文章我不知道是怎么来的&#xff0c;其次那些案例真的运行成功…

数据库浅谈之 Bloom Filter

数据库浅谈之 Bloom Filter HELLO&#xff0c;各位博友好&#xff0c;我是阿呆 &#x1f648;&#x1f648;&#x1f648; 这里是数据库浅谈系列&#xff0c;收录在专栏 DATABASE 中 &#x1f61c;&#x1f61c;&#x1f61c; 本系列阿呆将记录一些数据库领域相关的知识 &am…