android init进程分析 基本流程
来源:互联网 发布:js 参数中有双引号 编辑:程序博客网 时间:2024/05/21 11:10
(懒人最近想起我还有csdn好久没打理了,这个Android init躺在我的草稿箱中快5年了,稍微改改发出来吧)
android设备上电,引导程序引导进入boot(通常是uboot),加载initramfs、kernel镜像,启动kernel后,进入用户态程序。第一个用户空间程序是init, PID固定是1.在android系统上,init的代码位于/system/core/init下,基本功能有:
- 管理设备
- 解析并处理启动脚本init.rc
- 实时维护这个init.rc中的服务
init进程的系统初始化和服务流程,可以简单的看下init.c中的main函数。这里简要分析一下这个函数的主要作用,细节不展开或后继再展开。
简要说下main函数的各项操作吧:
以上这段,是main函数入口的第一句,这是判断是跑那个程序。
/system/core/init 这里面的一份代码,编出的二进制可执行程序init,实际是分为三个程序运行的,指示大家共享一份代码而已。三份分别是:
/init: 实际init可执行程序
/sbin/ueventd:ueventd daemon程序,是init的软链接
/sbin/watchdogd: watchdogd daemon程序,也是init的软链接。
我们都知道,main函数的参数argv的第一个,argv[0]为自身运行目录路径和程序名,这里就根据这个条件来判断代码走的路径。为何这样做?其实完全可以再另外写一个ueventd或watchdogd的一套程序,定义main函数啊。其实这里原因也是很简单,他们共享了太多东西,直接写到一起多简单!就像busybox或toolbox集成那么多命令工具一样的道理。
清理umask,这个主要是文件权限的问题,设了umask,可以全局mask掉一些文件权限。
Linux需要的dev,proc, sys等文件系统的加载。
创建一个/dev/.booting文件。 /dev是内存文件系统,不会保存的,每次开机都要重新创建。这个是指示,目前在booting过程中,具体干什么用的,介绍ueventd的时候就清楚了。就是加载设备的fimware用的。
这三句,分别是将 stdin,stdout和stderr先初始化到/dev/__null__,这样用printf或其他打印的,都输出不了,也不会引起其它异常(这个阶段,其实不能用,会出错的)。
注意这个/dev/__null__是临时起的名字,创建node后删了,不影响系统真正的/dev/null,这里只需要fd即可,有了fd后,文件名就无用了,有了还会有干扰。
klog_init,是将init进程中的log,打印到内核printk的log buffer中的方法。这对调试init很有帮助,毕竟此时没有shell,通用的log输出方法,如printf等还不能工作,借助底层已有的内核调试功能当然是最好的了。
property的初始化也是在这里,property读取可以在各个用户进程中做,但设置的入口必须是到init进程中来。在4.4上,property这块修改了好多,现在是通过字典树的方式存储,可以支持更多的property属性。
从 /proc/cpuinfo中读到hardware信息,设置到ro.hardware属性中,便于后面解析 init.${ro.hardware}.rc使用
kernel的command参数,解析后也放到property中,供以后的子进程或其他服务等使用。
selinux的初始化和检查,没仔细研究selinux,则个检查过程有时候还挺耗费时间的。
这个是加载并设置properties。这些是预置的property,通常是/system/build.prop和default.prop文件中预置的那些property。
这是开始解析init.rc文件了。细节和init.rc的格式、写法不说了,网上到处都是。主要说一下常见问题:
1. 下载代码的服务器,umask有时候可能会有影响,init.rc文件other和group用户是不能有写权限的,编译的PC的umask最好设置成0022。
2. init.rc文件严格来说只是配置文件,不算脚本,循环、条件判断等等都不支持的,不要想这里能干太多事情。
这是开始处理init.rc中parser好的各个命令了。
action_for_each_trigger是对此类trigger所在呃所有命令,都加入到actions的list中去。对实际代码或项目上要全局的看一下,所有的*.rc的同一个trigger都一起处理的。
queue_builtin_action这是内建的actions,也是将actions动作加入到actions list中。
这里需要注意的是,各个trigger的加载顺序,先加入的先执行,后加入的后执行,要特别注意,尤其是要修改init.rc文件的时候,不了解这个容易因为前后依赖关系造成问题。
都准备好了的话,就到了服务处理阶段了,这是一个死循环,主要工作就是:
1. 将init.rc及内建的actions命令,一条一条执行
2. 负责对service的管理。
3. 对signal及进程退出的处理
4. 响应property设置的请求(设置都在init中统一设置,读取进程可以自己读共享内存)
有时候需要优化开机的话,可以测量一下execute_on_command中的命令执行时间,把较长的(比如大于50ms)的打印出来,再想办法优化一下。
每次循环,执行一条命令,检查是否有需要重启的服务..
多路polling,当polling到东西,就执行相应的动作。
timeout时间到,执行下轮循环。init.rc中的command没处理完的话,timeout是0,这样之前的actions list可以一顺下来都执行掉。
注意,init.rc中定义的服务,是在class_start这个command中做的。
- android init进程分析 基本流程
- android init进程分析 基本流程
- Android开机流程分析 -- init进程
- Android启动流程分析(四) init进程分析
- Android -- Android Init进程的处理流程分析
- android init 进程分析
- Android init进程分析
- Android Init进程分析
- Android Init进程分析
- android init 进程分析
- android init 进程分析 (2 初始化流程)
- Android启动流程分析(二) init进程的启动
- Android启动流程分析(三) init进程初窥
- Android开机流程分析 -- init进程之配置文件解析
- Android -- Init进程对属性系统的处理流程分析
- Android 启动分析 init进程 init.rc
- android init进程分析 ueventd
- Android init进程启动分析
- vfio 通过VFIO_IOMMU_MAP_DMA 得到iommu映射后的地址。这样就等于user space直接使用iommu接口
- Android运行时异常“Binary XML file line # : Error inflating class”
- 基础的正则表达式
- WebGL框架:Three.js和Babylon.js的比较
- Redis——windows环境安装redis和redis sentinel部署
- android init进程分析 基本流程
- Web测试基于Apache2发布的SVN项目
- 作业、进程、管程概念区别
- json数据格式
- 空结构体struct{}解析
- 微信小程序 js动态给前台元素绑定事件
- 高性能IO模型浅析
- TaskAffinit属性详解
- 移动平台对 META 标签的定义