前文已经介绍完init进程第一阶段的初始化,接下来咱们开始讲解init进程第二阶段初始化过程,首先是属性的设置。android
如代码3-10所示,第二阶段一开始,即在“/dev”目录下建立“.booting”文件,以通知其它进程当前正处于启动过程。ionic
close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
代码 3-10 建立“/dev/.booting”函数
在Android系统中,属性是一种特殊的资源,Android系统经过属性暴露设备和运行时信息,应用程序经过读写属性可以得到相应的信息,以及控制系统的行为,如代码3-11所示是属性的初始化。性能
property_init();[1]
代码 3-11 main()-属性内存区域初始化命令行
在Android系统中,全部进程共享系统设置值,为此提供了一块属性内存区域。init进程调用代码3-12所示的property_init()函数,建立并初始化该内存区域。具体实现是property_init()函数经过调用__system_property_area_init()[2]函数完成。code
首先,__system_property_area_init()函数在顶级目录下建立 “/dev/__properties__”子目录,用于保存属性的上下文文件。然后打开“/property_contexts”[3]文件,遍历其中的属性前缀及控制访问权限的上下文,将它们加载到内存中的链表。随后将链表中的每个上下文在“/dev/__properties__”目录中都建立一个同名的文件,其中保存着受其控制的属性。最后把“/dev/__properties__”中的上下文文件映射到共享内存中,实现对属性的权限控制。进程
系统中其它进程经过执行中的进程所提供的API访问属性域中的设置值,但更改属性值仅能在init进程中进行。当修改属性值时,要预先向init进程提交值变动请求,而后init进程处理该请求,并修改属性值。内存
代码3-12将属性初始化到内存中。资源
process_kernel_dt(); (1) process_kernel_cmdline(); (2) export_kernel_boot_props(); (3)
代码 3-12 main()-属性初始化cmd
(1)初始化DT(Device Tree)的属性集,即访问“/proc/device-tree/firmware/android ”目录,先看compatible文件内容是不是“android,firmware”,而后这个目录下每一个文件名做为属性,文件里面的内容做为属性值。
(2)处理内核命令行,读取“/proc/cmdline”文件中的内容,而后调用import_kernel_nv()函数设置系统属性,此处只将“/proc/cmdline”中前缀为“androidboot.”的值设置到属性中。1中设置的DT属性集优先级高于此处设置的属性。
(3)设置内核启动的变量,根据系统已有的属性设置,若有值则保持不变,不然设置成初始值。
上述步骤基本就将Android系统所需的属性初始化好。正如前面咱们介绍的,init进程是其它全部进程的父进程,它须要监视和处理子进程的终止,为此须要初始化信号处理器,下一篇咱们将介绍这方面的内容。
[1] property_init()函数在system/core/init/property_service.cpp中定义。
[2] __system_property_area_init()函数在bionic/libc/bionic/system_properties.cpp中定义。
[3] property_contexts文件定义在system/sepolicy/property_contexts。