init是在内核启动后,在用户空间启动的第一个用户级进程init进程。内核在经过start_kernel() ---> init_post() ---->run_init_process() ------>启动init进程。在内核启动过程中,需要设置内核启动选项时,应设置为"init = /init"。如果不存在该文件或未指定,则在/sbin 、/etc、 /bin目录中查找init文件。
android启动init进程,那它做了哪些事情呢?
android的init进程主要提供了四大功能:
一、处理子进程终止
通过注册信号处理器来处理子进程终止。
static void sigchld_handler(int s){
write(signal_fd,&s,1);
}
(这个可以参考linux中进程间的通信)
二、生成设备驱动节点
通过mkdir()和mount()函数生成并挂载目录
几种文件系统:
1.tmpfs 虚拟内存文件系统,典型的tmpfs文件系统完全驻留在RAM中,读写速度远快于闪存或硬盘文件系统。
/dev目录保存中硬件设备访问所需要的设备驱动程序。在android中,将相关目录作tmpfs,可以大幅提升设备访问速度。
2.devpts是一种虚拟终端文件系统
3.proc是一种虚拟文件系统,只存在于内存中,而不占用外存空间。借助此文件系统,应用程序可以与内核内部数据结构进行交互。
4.sysfs文件是一种特殊的文件系统,在linux kernel 2.6中引入,用于将系统中的设备组织成层次结构,并向用户模式程序提供详细的内核数据结构信息
将proc、devfs、devpts三种系统统一起来。
生成log设备: open_devnull_stdio(); log_init();
open_devnull_stdio()将标准输出文件重定向至--null--设备中。这就意味做,无法通过标准输入输出查看输出信息,但log_init()函数,提供了log信息设备,生成/dev/__kmsg__设备文件节点。该节点调用内核信息输出函数printk()。
#define ERROR(x...) log_write(3,"<3>init:" x)
#define NOTICE(x...) log_write(5,"<5>init:" x)
#define INFO(x...) log_write(6,"<6>init:" x);
init进程通过__kmsg__设备定义用于输出信息的宏。关于宏输出信息,可以通过dmesg使用程序进程确定,dmesg用于显示内核信息。
设备文件生成后,开始解析 init.rc文件
parse_config_file("/init.rc");
三、提供属性服务
在android平台中,为了让运行中的所有进程共享系统运行时所需要的各种设置值,系统开辟了属性存储区域(Android shared Memory)
void property_init(void){
init_property_area();
load_properties_from_file(PROP_PATH_RAMDISK_DEFAULT);
}
并提供API访问该区域,该区域的属性由key和value构成。在android平台中,所有进行中的进程都可以访问属性值,但仅有init进程才能修改属性值。
在访问或更改属性值时,使用的函数分别为property_get()与property_set()
四、保存系统所需的环境变量
init.rc和属性服务一般都是设置相关环境变量。