Androidinit启动过程分析分析android的启动过程,从内核之上,我们首先应该从文件系统的init开始,因为init是内核进入文件系统后第一个运行的程序,通常我们可以在linux的命令行中指定内核第一个调用谁,如果没指定那么内核将会到/sbin/,/bin/等目录下查找默认的init,如果没有找到那么就报告出错。下面是曾经用过的几种开发板的命令行参数:S3C2410启动参数:noinitrdroot=/dev/nfsnfsroot=192.168.2.56:/nfsroot/rootfsip=192.168.2.188:192.168.2.56:192.168.2.56:255.255.255.0::eth0:onconsole=ttySAC0S3C2440启动参数:setenvbootargsconsole=ttySAC0root=/dev/nfsnfsroot=192.168.2.56:/nfsroot/rootfsip=192.168.2.175:192.168.2.56:192.168.2.201:255.255.255.0::eth0:onmem=64Minit=/initmarvell310启动参数:bootroot=/dev/nfsnfsroot=192.168.2.56:/nfsroot/rootfs,rsize=1024,wsize=1024ip=192.168.2.176:192.168.2.201:192.168.2.201:255.255.255.0::eth0:-Onconsole=ttyS2,115200mem=64Minit=/initinit的源代码在文件:./system/core/init/init.c中,init会一步步完成下面的任务:1.初始化log系统2.解析/init.rc和/init.%hardware%.rc文件3.执行early-initactioninthetwofilesparsedinstep2.4.设备初始化,例如:在/dev下面创建所有设备节点,下载firmwares.5.初始化属性服务器,Actuallythepropertysystemisworkingasasharememory.LogicallyitlookslikearegistryunderWindowssystem.6.执行initactioninthetwofilesparsedinstep2.7.开启属性服务。8.执行early-bootandbootactionsinthetwofilesparsedinstep2.9.执行Executepropertyactioninthetwofilesparsedinstep2.10.进入一个无限循环towaitfordevice/propertyset/childprocessexitevents.例如,如果SD卡被插入,init会收到一个设备插入事件,它会为这个设备创建节点。系统中比较重要的进程都是由init来fork的,所以如果他们他谁崩溃了,那么init将会收到一个SIGCHLD信号,把这个信号转化为子进程退出事件,所以在loop中,init会操作进程退出事件并且执行*.rc文件中定义的命令。例如,在init.rc中,因为有:servicezygote/system/bin/app_process-Xzygote/system/bin--zygote--start-system-serversocketzygotestream666onrestartwrite/sys/android_power/request_statewakeonrestartwrite/sys/power/stateon所以,如果zygote因为启动某些服务导致异常退出后,init将会重新去启动它。intmain(intargc,char**argv){...//需要在后面的程序中看打印信息的话,需要屏蔽open_devnull_stdio()函数open_devnull_stdio();...//初始化log系统log_init();//解析/init.rc和/init.%hardware%.rc文件parse_config_file(/init.rc);...snprintf(tmp,sizeof(tmp),/init.%s.rc,hardware);parse_config_file(tmp);...//执行early-initactioninthetwofilesparsedinstep2.action_for_each_trigger(early-init,action_add_queue_tail);drain_action_queue();.../*executeallthebootactionstogetusstarted*//*执行initactioninthetwofilesparsedinstep2*/action_for_each_trigger(init,action_add_queue_tail);drain_action_queue();.../*执行early-bootandbootactionsinthetwofilesparsedinstep2*/action_for_each_trigger(early-boot,action_add_queue_tail);action_for_each_trigger(boot,action_add_queue_tail);drain_action_queue();/*runallpropertytriggersbasedoncurrentstateoftheproperties*/queue_all_property_triggers();drain_action_queue();/*enablepropertytriggers*/property_triggers_enabled=1;...for(;;){intnr,timeout=-1;...drain_action_queue();restart_processes();if(process_needs_restart){timeout=(process_needs_restart-gettime())*1000;if(timeout重要的数据结构两个列表,一个队列。staticlist_declare(service_list);staticlist_declare(action_list);staticlist_declare(action_queue);*.rc脚本中所有service关键字定义的服务将会添加到service_list列表中。*.rc脚本中所有on关键开头的项将会被会添加到action_list列表中。每个action列表项都有一个列表,此列表用来保存该段落下的Commands脚本解析过程:parse_config_file(/init.rc)intparse_config_file(constchar*fn){char*data;data=read_file(fn,0);if(!data)return-1;parse_config(fn,data);DUMP();return0;}staticvoidparse_config(constchar*fn,char*s){...caseT_NEWLINE:if(nargs){intkw=lookup_keyword(args[0]);if(kw_is(kw,SECTION)){state.parse_line(&state,0,0);parse_new_section(&state,kw,nargs,args);}else{state.parse_line(&state,nargs,args);}nargs=0;}...}parse_config会逐行对脚本进行解析,如果关键字类型为SECTION,那么将会执行parse_new_section()类型为SECTION的关键字有:on和sevice关键字类型定义在Parser.c(system\core\init)文件中Parser.c(system\core\init)#defineSECTION0x01#defineCOMMAND0x02#defineOPTION0x04关键字属性capability,OPTION,0,0)class,OPTION,0,0)class_start,COMMAND,1,do_class_start)class_stop,COMMAND,1,do_class_stop)console,OPTION,0,0)critical,OPTION,0,0)disabled,OPTION,0,0)domainname,COMMAND,1,do_domainname)exec,COMMAND,1,do_exec)export,COMMAND,2,do_export)group,OPTION,0,0)hostname,COMMAND,1,do_hostname)ifup,COMMAND,1,do_ifup)insmod,COMMAND,1,do_insmod)import,COMMAND,1,do_import)keycodes,OPTION,0,0)mkdir,COMMAND,1,do_mkdir)mount,COMMAND,3,do_mount)on,SECTION,0,0)oneshot,OPTION,0,0)onrestart,OPTION,0,0)restart,COMMAND,1,do_restart)service,SECTION,0,0)setenv,OPTION,2,0)setkey,COMMAND,0,do_setkey)setprop,COMMAND,2,do_setprop)setrlimit,COMMAND,3,do_setrlimit)socket,OPTION,0,0)start,COMMAND,1,do_start)stop,COMMAND,1,do_stop)trigger,COMMAND,1,do_trigger)symlink,COMMAND,1,do_symlink)sysclktz,COMMAND,1,do_sysclktz)user,OPTION,0,0)write,COMMAND,2,do_write)chown,COMMAND,2,do_chown)chmod,COMMAND,2,do_chmod)loglevel,COMMAND,1,do_loglevel)device,COMMAND,4,do_device)parse_new_section()中再分别对service或者on关键字开头的内容进行解析。...caseK_service:state-context=parse_service(state,nargs,args);if(state-context){state-parse_line=parse_line_service;return;}break;caseK_on:state-context=parse_action(state,nargs,args);if(state-context){state-parse_line=parse_line_action;return;}break;}...对on关键字开头的内容进行解析staticvoid*parse_action(structparse_state*state,intnargs,char**args){...act=calloc(1,sizeof(*act));act-name=args[1];list_init(&act-commands);list_add_tail(&action_list,&act-alist);...}对service关