概述
init的任务
创建zygote:JAVA世界的第一个进程
提供属性服务(property service):管理系统属性
加载service
init源码分析
入口函数:init.c:main.c
路径:systemcoreinit
完成任务:
解析配置文件init.rc
执行各个阶段动作:early-init、init、late-init(创建zygote)
调用property_init初始化属性相关资源,property_service_init_action->start_property_service启动属性服务
init进入无限循环,等待并执行一些事情,如客户端更改属性服务。
init.rc语法分析
关键字
section:
service:以service开头,服务是指那些需要在系统初始化时就启动或退出时自动重启的程序.
action:以on开头,动作表示了一组命令(commands)组成,当触发器的条件满足时,这个动作会被加入到已被执行的队列尾
option:选项是用来修改服务的。它们影响如何及何时运行这个服务.
class main
trigger:触发器用来描述一个触发条件,当这个触发条件满足时可以执行动作
commands:要执行的动作
解析配置文件init.rc
init_parse_config_file(“/init.rc”):systemcoreinitinit_parser.c
读取init.rc
parse_config做真正解析
parse_config:systemcoreinitinit_parser.c
找到配置文件的一个SECTION,针对不同的section使用不同的解析函数来解析
解析zygote
zygote被定义成service section
解析section入口函数:parse_new_section:systemcoreinitinit_parser.c
根据kw这个参数判断是k_on还是k_service(这些在keywords.h有定义)
KEYWORD(service, SECTION, 0, 0),第一个参数为service或on或import是SECTION
当kw为k_service时,调用两个函数:
1、parse_service:systemcoreinitinit.h
搭建一个struct service结构,将zygote这个service加到全局链表service_list中
2、parse_line_service:根据配置文件的内容填充struct service结构体,结果如下:
zygote解析结果图
service_list是全局链表,保存解析后的service
socketinfo保存zygote的socket
onrestart的commands指向zygote的3个command
init如何控制service
在init.c的main函数中,要分别执行early-init、init、late-init、boot四个阶段的动作,这些动作来自之前的解析文件init.rc
init.rc的zygote服务中有这样一句话:class main
(服务默认创建的时候classname为“default”,这里通过“class main”来修改classname为“main”)
函数:
1、action_for_each_trigger:将各个阶段的section的command加入队列中
2、queue_builtin_action:执行队列的command
在on boot阶段,有class_start main,对应的函数是do_class_start
do_class_start
路径:systemcoreinitbuiltins.c
任务:从service_list链表中找到classname和参数一致的service, 然后调用service_start_if_not_disabled->service_start_if_not_disabled->service_start(systemcoreinitinit.c)
service_start的任务:
1、调用fork创建新进程
2、调用execve执行/system/bin/app_process,这样就进入app_process的main函数中。
问题:struct service 中的onrestart没有用到?
zygote重启
在init.c的main函数中,signal_init_action被调用,再调用signal_init(systemcoreinitsignal_handler.c)
signal_init调用socketpair创建已经connect好的socket
当zygote死掉后,即子进程退出,init的信号处理函数sigchld_handler被调用,该函数往创建的socket的一端写数据,则另一端会接收到数据,此时init从poll函数中返回,init.c->main.c调用handle_signal(systemcoreinitsignal_handler.c)->wait_for_one_process
wait_for_one_process的任务
找到死掉的那个service,即zygote进程
杀掉zygote所有子进程,则如果zygote死掉后,JAVA世界将崩溃
如果设置了SVC_CRITICAL标志,4分钟之内若重启次数超过4次,则进入“recovery”模式
执行struct service中onrestart的command
问题:zygote死后如何重启?
在init.c的main函数中,当poll函数返回后,继续进入下一轮循环
restart_processes() :重启被标志为SVC_RESTARTING的service,此时zygote被重启
属性服务
1、作用:
就像window的注册表一样,Android系统提供属性服务,系统重启时可根据这些属性进行初始化,应用程序可查询和修改属性
2、属性服务实现:
创建存储空间
客户端获取存储空间
启动属性服务器
处理设置属性请求
属性服务实现
1、init.c的main函数:property_init->init_property_area(systemcoreinitproperty_service.c)->init_workspace:创建一块共享内存,用于存储系统属性
2、在property_service.c中调用__system_property_area_init->map_prop_area_rw(bioniclibcbionicsystem_properties.cpp)->mmap
3、init.c的main函数:property_service_init_action->start_property_service(systemcoreinitproperty_service.c):创建一个socket用于与客户端更改属性的通讯
4、在init.c的main函数中的循环当中处理设置属性请求:handle_property_set_fd(systemcoreinitproperty_service.c)
连接TCP、取出消息、做出响应(init_property_set)即添加属性
问题:客户端如何请求更改属性?systemcorelibcutilsproperties.c->property_set:发送请求
zygote分析
zygote由init进程创建
zygote的任务:
1、创建JAVA虚拟机
2、注册JNI函数
3、通过JNI进入JAVA世界
3.1、注册一个socket
3.2、预加载类和资源
3.3、创建system_server进程
3.4、处理socket中的客户端连接和请求
说白了就是JAVA世界需要的东西,zygote为你准备好
如何进入zygote进程的
init进程解析完init.rc后会执行一系列动作,其中在on boot阶段,有class_start main,对应的函数是do_class_start,这里最后通过Linux系统调用函数execve进入zygote进程,也就是app_process
app_process的源文件是app_main.cpp(frameworksbasecmdsapp_process)
在app_main.cpp中调用AppRuntime类(继承AndroidRuntime)中的start,传递的参数是com.android.internal.os.ZygoteInit,下面进入AndroidRuntime.start函数
AndroidRuntime.start
路径:frameworksbasecorejniAndroidRuntime.cpp
1、创建JAVA虚拟机:startVm
1.1、设置参数(如虚拟机大小),1.2、JNI_CreateJavaVM创建虚拟机
2、注册JNI函数:startReg(JAVA需要调用JNI实现)
register_jni_procs,参数:gRegJNI,这是个全局数组,包含JNI函数
3、进入JAVA世界:CallStaticVoidMethod,参数为com.android.internal.os.ZygoteInit,下面分析ZygoteInit.java的main函数
进入JAVA世界,此时还是处于zygote进程
路径:frameworksbasecorejavacomandroidinternalosZygoteInit.java
任务:
1、注册zygote用的socket
registerZygoteSocket(),用于与其他程序通讯
2、预加载类和资源
preload()->preloadClasses、preloadResources。
PRELOADED_CLASSES:frameworksbasepreloaded-classes
3、创建system_server进程
startSystemServer()->forkSystemServer->fork
4、处理socket中的客户端连接和请求
runSelectLoop()->selectReadable使用select多路复用处理请求
system_server的任务
在哪里创建:
forkSystemServer通过JNI 调用com_android_internal_os_Zygote_nativeForkSystemServer
路径:frameworksbasecorejnicom_android_internal_os_Zygote.cpp
任务:入口Zygoteinit.java->handleSystemServerProcess->RuntimeInit.java->zygoteInit->applicationInit->invokeStaticMain:抛出异常,异常被ZygoteInit.java的main函数捕获,并进入caller.run()函数
1、处理异常并进入SystemServer.java的main函数
2、创建各种服务
system_server转交任务给SystemServer.java
路径frameworksbaseservicesjavacomandroidserverSystemServer.java
任务:
启动各类系统服务,包括ActivityManager服务
最后
以上就是寒冷枫叶为你收集整理的Android init.rc和zygote进程分析的全部内容,希望文章能够帮你解决Android init.rc和zygote进程分析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复