浅析kernel启动的第1个用户进程init如何解读init.rc脚本
2010-05-26 19:14
645 查看
浅析kernel启动的第1个用户进程init如何解读init. rc脚本 首先解读 1. on init字段到来, state- > context为新申请到的struct action结构体, 并将其挂接到action_list尾部, 然后初始化处理方法, 之后该section内的所有command都将挂接到act- > commands链表上, 这样也就有了立体层次[ luther. gliethttp] . state- > parse_line = parse_line_action; 这样以后的"行脚本" 将使用这个方法来做处理. 2. loglevel 3因为为cmd, 所以会将动态malloc一个struct command缓冲区, cmd = malloc ( sizeof ( * cmd) + sizeof ( char * ) * nargs) ; cmd- > func = kw_func( kw) ; cmd- > nargs = nargs; memcpy ( cmd- > args, args, sizeof ( char * ) * nargs) ; list_add_tail( & act- > commands, & cmd- > clist) ; //先将cmd结构体放到list链表尾,后面会集中处理. 3. 之后就都是上面的重复工作了. 一个on和一个service都将创建一个新的struct action结构体, 之后作为当前state- > context来处理接下来的所有cmd, 所以接下来的所有cmd也就都将挂接到这个新的act- > commands链表上, 感觉这样一来脚本非常有层次感, 管理起来也很舒服. 4. 对于service服务段处理, 如果为service命令, 那么, 先检查service_list链表上是否已经有了同名的服务[ luther. gliethttp] . svc = service_find_by_name( args[ 1] ) ; if ( svc) { parse_error( state, "ignored duplicate definition of service '%s'/n" , args[ 1] ) ; return 0; } svc = calloc ( 1, sizeof ( * svc) + sizeof ( char * ) * nargs) ; if ( ! svc) { parse_error( state, "out of memory/n" ) ; return 0; } svc- > name = args[ 1] ; svc- > classname = "default" ; memcpy ( svc- > args, args + 2, sizeof ( char * ) * nargs) ; svc- > args[ nargs] = 0; svc- > nargs = nargs; list_add_tail( & service_list, & svc- > slist) ; //将这个service控制结构体添加到service_list链表尾. 然后将paser的方法指向service方法 state- > parse_line = parse_line_service; //以下所有参数都将使用parse_line_service进行解析. 5. service命令后边的参数都将用来改变该service控制结构体里的项, 不同的service命令, 对args有不同的解析方式, 都在parse_line_service中完成, 比如: 1 service dund / system / bin/ dund / 2 - - listen - - channel= 5 - - nodetach - - pppd= / system / bin/ pppd / 3 192. 168. 0. 100: 192. 168. 0. 101 nodefaultroute unit 1 linkname bluetooth 4 user bluetooth 5 group bluetooth net_bt_admin 6 disabled 那么1行开始将申请一个service结构体, 然后挂接到service_list链表上, 之后的5行都是用来控制这个service结构体里边的数据项, 直到在行首遇到下一个service关键字或者on才会停止[ luther. gliethttp] . 好了, 基本的命令字和立体的脚本解析结构, 已经说完了, 那么从init. rc脚本解析出来的咚咚在啥时候用呢, 1. 对于on节提供的对外接口 void action_for_each_trigger( const char * trigger, void ( * func) ( struct action * act) ) void queue_property_triggers( const char * name, const char * value) void queue_all_property_triggers( ) 举个例子 action_for_each_trigger( "early-init" , action_add_queue_tail) ; action_for_each_trigger( "init" , action_add_queue_tail) ; action_for_each_trigger( "early-boot" , action_add_queue_tail) ; action_for_each_trigger( "boot" , action_add_queue_tail) ; 2. 对于service节提供的对外接口 struct service * service_find_by_name( const char * name) struct service * service_find_by_pid( pid_t pid) void service_for_each_class( const char * classname, void ( * func) ( struct service * svc) ) void service_for_each_flags( unsigned matchflags, void ( * func) ( struct service * svc) ) 举个例子 int do_start( int nargs, char * * args) { struct service * svc; svc = service_find_by_name( args[ 1] ) ; if ( svc) { service_start( svc) ; } return 0; }
相关文章推荐
- 浅析kernel启动的第1个用户进程init如何解读init.rc脚本
- 第1个用户进程init和init.rc脚本
- Android如何配置init.rc中的开机启动进程(service)【转】
- init进程 && 解析Android启动脚本init.rc && 修改它使不启动android
- RK3128系统&驱动开发分享——(四)init.rc及开机启动脚本
- /etc/rc.d/init.d/functions 脚本详解【如何写出像红帽一样NB的启动脚本】
- init进程 && 解析Android启动脚本init.rc && 修改它使不启动android && init.rc中启动一个sh文件
- Android init.rc如何启动service去执行sh脚本
- Android如何配置init.rc中的开机启动进程(service)
- Android init.rc如何启动service去执行sh脚本
- Android init.rc如何启动service去执行sh脚本
- Android init.rc如何启动service去执行sh脚本
- Android启动脚本init.rc
- 基于android2.3.5系统:Linux如何启动Andriod的守护进程init
- Android启动脚本init.rc简介
- Android init.rc 进程启动详解
- Android启动脚本init.rc
- Android启动脚本init.rc
- Android在init.rc中加入脚本开机安装APK并启动APK的服务
- Android启动脚本init.rc分析