android系统启动流程之init启动分析

 先根据上图来描述下安卓整个系统的启动流程:

当上电时,系统先执行BootRom, 加载引导程序执行。

然后进入bootloader,在安卓系统中基本上这个bootloader是uboot, 通过uboot引导启动内核,此时运行在kernel空间,这时的idle属于内核中的进程,它的pid = 0,它负责初始化进程、内存、驱动等相关工作,随后由idle启动fork一个为init进程,这个属于用户空间的进程,pid = 1,然后再fork创建pid=2的kthreadd内核进程,这个是内核进程的鼻祖。init进程则是用户空间的鼻祖,应用空间的所有进程要么直接或间接都是由init进程创建的。

比如init会fork()创建zygote, 这个进程则是java进程的所有鼻祖,所有的java app均来自于zygote进程的fork操作,比如安卓非常重要的系统进程服务SystemServer也是由zygote孵化而来,SystemServer是zygote进程的大儿子,SystemServer进程被创建启动之后,将会创建系统所需要的各种Services, 如ActivityManagerService, WindowManagerService, PackageManagerServices等等,安卓系统中一共大约有90+种服务,均由SystemServer创建生成,因此所有的系统Service服务它们都属于SystemServer进程。

而app的启动过程,则是通过AMS通过发送socket消息给zygote进程,由zygote进程fork()创建这个app进程。

  •  init进程的启动

init进程的程序可执行源文件位于/system/bin/init中,前面的流程图可知init进程是由内核的idle进程启动的,先来看看内核中启动init进程的部分源码:

/kernel/common/init/main.c -->kernel_init():-->try_to_run_init_process("/bin/init"); //启动init进程。-->run_init_process("/bin/init");-->kernel_execve("/bin/init"); //还是熟悉的味道与配方

  init的入口函数是main.cpp文件的main函数,下面是真正的init的启动流程:

  main()://第一阶段重要工作://1挂载文件系统,创建文件//2重定向输入输出,重定向内核日志//3启动selinux_setup-->第一阶段:FirstStageMain(argc, argv);-->mount("tmpfs","dev","tmpfs"); //挂载虚拟文件系统mount("devpts","/dev/pts", "devpts",0,NULL)mount("proc", "/proc",..);mount("sysfs","/sys","sysfs");mount("selinuxfs",...);mount("tmpfs","/mnt")//创建一些设备结点mknod("/dev/kmsg");mknod("/dev/null");SetStdioToDevNULL();InitKernelLogging(); //日志重定向DoFirstStageMount(); //挂载一些重要的分区设备//启动selinux_setupchar* args[]={path, "selinux_setup"};execv(path, args);//参数传递进去继续执行。进入第二阶段:main()->SetupSelinux(argv):创建Selinux android强制访问机制-->SetStdioToDevNull(); //日志重定向InitKernelLogging();SelinuxSetupKernelLogging();SelinuxInitialize(); //linux安全策略初始化//Android --权限  用selinux最小权限原则来处理。char* args[]={path, "second_stage"};execv(path, args);//参数传递进去继续执行,进入第三阶段进入第三阶段:main()->SecondStageMain(argc, argv);-->SetStdioToDevNULL();InitKernelLogging(); //日志重定向PropertyInit(); //属性域初始化-->PropertyLoadBootDefaults();SelinuxSetupKernelLogging();SelabelInitialize();SelinuxRestoreContext();//恢复安全上下文//处理子进程的终止信号--防止僵尸进程Epoll epoll;InstallSignalFdHandler(&epoll);InstallInitNotifier(&epoll)StartPropertyService(&property_fd);//启动属性服务GetBuiltinFunctionMap();//命令与函数映射:如将mkdir命令-->mkdir函数匹配LoadBootScripts(am,sm); //解析init.rc文件while(1){ //进入while循环am.ExecuteOneCommand(); //执行解析出来的action里的指令auto pending_functions = epoll.Wait(epull_time);//等待}

下面看看LoadBootScripts它是如何进行init.rc文件的解析流程的:

LoadBootScripts(am,sm); //解析init.rc文件//创建解析器,action_manager结构可以保存所有的action列表//service_list:保存解析init.rc中的所有服务。-->Parser parser = CreateParser(action_manager, service_list);-->parser.AddSectionParser("service"); //service解析器parser.AddSectionParser("on"); //on解析器parser.AddSectionParser("import");//import解析器parser.ParseConfig("/system/etc/init/hw/init.rc");//解析init.rc-->ParseConfigFile(path); -->ParseData(path, &config_contents.value());//具体的解析过程在里面,
  • 总结

init进程的重要处理事务:
1 挂载文件
2 设置selinux --安全策略
3 开启属性服务,注册到epoll中
4 解析init.rc文件
5 执行循环处理脚本 --启动ServiceManager zygote等
6 循环等待

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Go 基础篇】Go语言中的自定义错误处理

错误是程序开发过程中不可避免的一部分,而Go语言以其简洁和高效的特性闻名。在Go中,自定义错误(Custom Errors)是一种强大的方式,可以为特定应用场景创建清晰的错误类型,以便更好地处理和调试问题。本文将详…

基于Googlenet深度学习网络的交通工具种类识别matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ....................................................................................% 获…

SpringCloud之断路器聚合监控

一、Hystrix Turbine简介 看单个的Hystrix Dashboard的数据并没有什么多大的价值,要想看这个系统的Hystrix Dashboard数据就需要用到Hystrix Turbine。Hystrix Turbine将每个服务Hystrix Dashboard数据进行了整合。Hystrix Turbine的使用非常简单,只需要…

CSS中如何改变鼠标指针样式(cursor)?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ CSS中改变鼠标指针样式(cursor)⭐ 示例:⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅…

废品回收抢单派单小程序开源版开发

废品回收抢单派单小程序开源版开发 用户注册和登录:用户可以通过手机号码注册和登录小程序,以便使用废品回收抢单派单功能。废品回收订单发布:用户可以发布废品回收订单,包括废品种类、数量、回收地点等信息。废品回收抢单&#…

【CSS】网站 网格商品展示 模块制作 ( 清除浮动需求 | 没有设置高度的盒子且内部设置了浮动 | 使用双伪元素清除浮动 )

一、清除浮动需求 ( 没有设置高度的盒子且内部设置了浮动 ) 绘制的如下模块 : 在上面的盒子中 , 没有设置高度 , 只设置了一个 1215px 的宽度 ; 在列表中每个列表项都设置了 浮动 ; /* 网格商品展示 */ .box-bd {/* 处理列表间隙导致意外换行问题一排有 5 个 228x270 的盒子…

Aidex 移动端快速开发框架# RuoYi-Uniapp项目,uniapp vue app项目跨域问题

参考地址: manifest.json官方配置文档:manifest.json 应用配置 | uni-app官网 Chrome 调试跨域问题解决方案之插件篇: uni-app H5跨域问题解决方案(CORS、Cross-Origin) - DCloud问答 其实uni-app官方有解决跨域的办…

逆向抓包大神

0x01 前言 抓包应该是我们逆向的第一步,只有先抓到包,才能决定我们是否要进行脱壳、逆向。万一他没有加密、万一数据不是我们想要的那岂不是白忙活了。但是目前很APP都设置了门槛,比如新版的抖音、淘宝、天眼查等挂上代理就直接无数据或者就…

Skywalking Kafka Tracing实现

背景 Skywalking默认场景下,Tracing对于消息队列的发送场景,无法将TraceId传递到下游消费者,但对于微服务场景下,是有大量消息队列的业务场景的,这显然无法满足业务预期。 解决方案 Skywalking的官方社区中&#xf…

企业展示小程序的制作流程及关键步骤详解

在移动互联网时代,企业展示小程序已成为各个行业推广和展示的重要工具。搭建一个企业展示小程序不仅能够提高企业形象,还能够增加用户粘性和提升用户体验。下面我们来看一下如何从零基础搭建一个企业展示小程序,并顺利上线。 第一步&#xff…

R package org.Hs.eg.db to convert gene id

文章目录 install使用org.Hs.egENSEMBL将Ensembl id convert to gene idorg.Hs.egGENENAME 将Ensembl id convert to gene nameorg.Hs.egSYMBOL 将 gene symbol convert to gene id我现在有一些ensembl id 如何转为 gene name注意你会遇到一些record不全的情况,gtf文…

【Go Web 篇】从零开始:构建最简单的 Go 语言 Web 服务器

随着互联网的迅速发展,Web 服务器成为了连接世界的关键组件之一。而在现代编程语言中,Go 语言因其卓越的性能和并发能力而备受青睐。本篇博客将带你从零开始,一步步构建最简单的 Go 语言 Web 服务器,让你对 Go 语言的 Web 开发能力…

C++多线程编程——线程同步(保姆级-1.4W字)

目录 C线程同步 引入 互斥锁 std::mutex std::lock_guard类模板 unique_lock 成员方法 应用举例 std::lock()函数模板 std::call_once(flag、function) 懒汉式单例模式实例 unique_lock互斥锁方式 ​编辑 call_once方式 条件变量 std::condition 条件变量使…

【网络】IP网络层和数据链路层

IP协议详解 1.概念 1.1 四层模型 应用层:解决如何传输数据(依照什么格式/协议处理数据)的问题传输层:解决可靠性问题网络层:数据往哪里传,怎么找到目标主机数据链路层(物理层)&…

Windows商店引入SUSE Linux Enterprise Server和openSUSE Leap

在上个月的Build 2017开发者大会上,微软宣布将SUSE,Ubuntu和Fedora引入Windows 商店,反应出微软对开放源码社区的更多承诺。 该公司去年以铂金会员身份加入Linux基金会。现在,微软针对内测者的Windows商店已经开始提供 部分Linux发…

react +Antd Cascader级联选择使用接口数据渲染

1获取接口数据并将数据转换成树形数组 useEffect(() > {axios.get(/接口数据, {params: {“请求参数”},}).then((res) > {console.log(res);const getTreeData (treeData, pid) > {// 把数据转化为树型结构let tree [];let currentParentId pid || 0;for (let i …

大数据扫盲(2): 数据分析BI与ETL的紧密关系——ETL是成功BI的先决条件

着业务的发展每个企业都将产生越来越多的数据,然后这些数据本身并不能直接带来洞察力并产生业务价值。为了释放数据的潜力,数据分析BI(商业智能)成为了现代企业不可或缺的一部分。然而,在数据分析的背后,有…

VUE笔记(九)vuex

一、vuex的简介 1、回顾组件之间的通讯 父组件向子组件通讯:通过props实现 子组件向父组件通讯:通过自定义事件($emit)方式来实现 兄弟组件之间的通讯:事件总线($eventBus)、订阅与发布方式来实现 跨级组件的通讯…

word如何调整页码

文章目录 如何调整页码 如何调整页码 用 word 写报告的时候,经常遇到要求说是要从正文开始才显示页码,那如何实现呢 把鼠标放在我们正文的那一页的顶部,点击 布局 ,再点击分隔符,再点击连续 再点击编译页脚 选择你想要的页脚格式…

MySQL数据库基本操作

目录 一、数据库中常用的数据类型 二、常用命令与操作 1.DDL数据库定义语言 1、登录用户的数据库 2、查看当前服务器中的数据库 3、切换/进入数据库 并 查看数据库中包含的表 4、查看数据库中表的结构 5、创建数据库 7、展示创建数据表时的结构 8、创建表&#xff0c…