Android系统启动 init.rc解析

最近跟着同事做一个功能,中间有一段很值得我学习,通过property去触发service再去注册所需要的功能,看着好像挺简单的,debug的过程中不免会有很多问题吧,但最重要的首先要有这种思想,然后才能下手一步步去填坑

(1)添加我们自己的rc,以及所需要的services执行文件

其实不外乎就是两步:(一)是需要把我们编写的内容编出来 (二)是需要把编出的内容放在系统的位置中

vendor_product.mk
PRODUCT_PACKAGES += test_services           //services执行文件 - cpp文件
PRODUCT_PACKAGES += vendor.test_services.rc  //rc文件

在编译cpp的同级目录下添加rc文件以及修改Android.bp或Android.mk
Android.bp
init_rc: [ "vendor.test_services.rc", ],
or
Android.mk
LOCAL_INIT_RC := vendor.test_services.rc

out目录生成的路径
vendor/bin/test_services           
vendor/etc/init/vendor.test_services.rc

(2)编写vendor.test_servies.rc文件,通过property触发

动作(action):以关键字"on" 开头,表示一堆命令
服务(service):以关键字“service”开头,表示启动某个进程的方式和参数
on property触发机制和实现原理 1、启动时,如果属性满足设定条件会触发一次
2、系统运行中如果属性发生变化,且新值等于设定值,则触发一次

camera provider就不是oneshot类型的,oneshot启动结束后不会重启,而camera provider是会重启的。

service vendor.test_services /vendor/bin/test_services args //
	user root
	group root system
	oneshot                                     //oneshot表示这个service只被启动一次
	disable                                     //不随class自动启动,只有根据service名才启动;
on property:persist.vendor.test_services = *    //匹配任何值都可以
	start vendor.test_services.                 //除此之外还有classstart

触发方式除了property属性值条件触发还有

on on early-init:在初始化早期阶段触发
on init:在初始化阶段触发
on late-init:在初始化晚期阶段触发
on boot/charger:当系统启动/充电时触发

(3)编译执行文件test_services,通过传参内容判断注册功能

其实就是我们最初学习c/c++中写的最多的mian函数,细节省略,当然网上也有很多使用.sh作为执行文件的,这里其实我们用的就是高通本身就是有的example来进行修改的

char s_name[20] = "";
int main(int argc, char * argv[]){
	if(argc == 2)
		strlcpy(s_name, argv[1], sizeof(s_name))
		//Do it
	return 0;
}

(4)property属性的添加,以及设property需要注意sepolicy问题

Android 8.0 添加开机启动服务 test_services对应vendor.test_services.rc中定义的services,test_services_exec对应执行文件test_services
init_daemon_domain 是一个宏,用来使 test_services域生效,如果没有填加sepolicy的配置,则会报错
init:service monitor does not have a SELinux domain defind

file_contexts 
/(vendor|system/vendor)/bin/test_services                                        u:object_r:test_services_exec:s0

test_services.te
type test_services, domain;
type test_services_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(test_services)
allow test_services vendor_sensors_prop:property_service { set };
allow test_services vendor_sensors_prop:file { getattr open read map };

get_prop(test_services, vendor_sensors_prop);

allow test_services stest_services:qipcrtr_socket { setopt getattr create write read };

property_context
persist.vendor.sensors.test_services        u:object_r:vendor_sensors_prop:s0
...

单编sepolicy并快速验证

(1)source  bulid/envsetup.sh (2)lunch  (3)mmm system/sepolicy
(4)adb push out\..\vendor\etc\selinux\.  /vendor/etc/selinux
   adb push out\..\system\etc\selinux\.  /system/etc/selinux
(5)adb reboot