安卓底层开发学习经验第十一期

这一期呢,我们主要是学习我们的 init 进程脚本如何解析我们的启动脚本的,我们 init 进程做完一些初始化的工作之后就会解析我们的启动脚本,他的启动过程主要分为下面几个部分
第一个就是使用init_parse_config_file 函数来解析我们的启动脚本,把我们的启动脚本的每一个命令全部解析到我们的一个列表中;
第二个就会调用 action_for_each_trigger queue_builtin_action 这两个函数把我们所解析的相关的操作加到我们的 action_queue 的队列中,然后就会从 action 队列中取相应的操作创建相关的服务或执行相关的命令,最后再去守护我们相关的服务
那么我们首先来看一下我们解析脚本的一个过程
首先我们会调用init_parse_config_file 来解析我们的 init.rc  ,在解析前,我们首先打开我们的 init.rc  ,然后调用 parse_config 这个函数来解析我们的启动脚本,在解析过程中主要涉及到以下几个数据结构和链表
我们的数据结构包括: import_list struct listnode
import_list 主要是用来保存我们 init.rc 中所导入的其他脚本文件,比如 init.usb.rc
struct listnode 主要是用来保存启动脚本中所有的操作命令
而我们的三个链表呢,是用来保存我们命令的这三个链表分别是: service_list  action_list  action_queue
service_list 主要是用来保存我们脚本中所有的服务
action_list  主要是用来保存我们所有的操作
action_queue 主要是执行的链表
我们解析完的服务和相关的操作全都放在 service_list action_list 这两个链表中,然后我们会使用其他的方法,把我们的在初始化过程中需要执行的服务和命令添加到我们的 action_queue 链表中,最后由我们的 init 进程根据 action_queue 中服务和命令来执行相关的操作,我们代开代码来看一下 init_parse_config_file 函数
他首先会打开我们这个文件,然后调用parse_config 这个函数来解析这个文件,这个解析文件就是一个简单的语法解析器
在这里会有一个parse_state 变量,我们后边在看,我们再看他解析过程中,首先就是调用我们的 next_token  next_token 就是一个语句中的最小单元,我们再看一下我们的启动脚本
我们一个最小的单元就是指:on  early-init  write  、、 proc/1/oom_adj  -16  他们都是独立的单元,下面我们来看一下我们的 next_token
他一共有三个返回值,第一个是T_EOF ,也就是我们的文件解析完成,完成之后就走到了我们的 parser_done
他在这里就会把我们的import_list 列表中所包含的其他的 init 脚本,在这里重新做解析,这就是在解析完之后他会导入其他的脚本
那我们的第二个返回值是 T_NEWLINE ,他在执行的过程中会首先看一下我们的关键字,也就是我们返回的第一个 args ,如果说第一个 args SECTION 的话,那么他就会调用 state.parse_line 做一个解析,然后调用 parse_new_section 这个函数,稍后我们会看到这两个函数的意思
我们再来看一下第三个返回值,他是 T_TEXT ,他在这里就相当于我们命令中的一个参数。
下面我们来看一下我们 next_token 的一个具体实现
他的解析过程是根据我们这里的变量 parse_state 来决定的,这里的 parse_state 有一个 nexttoken  ,这个 nexttoken 保存着我们解析的一个状态,如果说我们在上一次解析中把这个 nexttoken 给设置了,那么我们会首先执行上次所设置的状态,在这个状态中会直接返回,然后把这个状态直接清 0 ,交给我们的 parse_config ,而我们没有设置这个状态呢,我们就会真正的去解析这个脚本
他解析的过程呢是一个字符一个字符的去判断,如果我们遇到的是 0 ,那么我们就认为这个文件解析完成,返回一个 T_EOF ,如果我们遇到一个“ \n ”,那么就说明我们遇到了一个新的一行,这时就会返回一个 T_NEWLINE ,如果我们遇到其他字符可以继续操作,如果说我们遇到一个 # 号,这个是一个注释行,我们可以把它忽略,然后返回一个新的行。
其实从第一个 for 循环我们可以看到,我们这个 for 循环的作用就是把我们脚本中没用的字符,比如说 \n  \t  、以及无用的空格等给清除掉,过滤掉,因为我们调用一次肯定是上次遇到了一个完整的单词,或者说遇到了一个完整的行,进来之后呢,他里边第一个必须遇到一个正常的字母,然后才能说明他有一个新的 token ,这是我们第一个 for 循环的作用。如果我们在 for 循环最后遇到一个字符,就会调到我们的 text 标签中执行,下面我们来看一下我们的 text
在这里主要是解析我们最小的一个token ,如果说我们上一个遇到了一个字符,那么他在这里就会解析这个单词的结束,如果下一个是 0 的话,他在这里就会走一下 textdone  ,如果我们遇到的是空格、 \n  、  \t  \r 我们就说我们遇到了一个完整的单词 ,这个单词就会返回,如果遇到 \n  ,我们可以看到我们在这里设置了 nexttoken ,是 T_NEWLINE ,然后在这里也走到了 textdone ,如果我们遇到了一个引号,那么它就会去做一些相关的事情,接下来来我们来看一下我们的 textdone
在这里textdone 他就是标记了这个字符的一个级数位置,然后返回了一个 T_TEXT ,也就是返回了一个完整的单词,这就是我开门 nexttoken 所做的一个操作,了解了 nexttoken 之后呢,我们就知道了解析的一个最小的元素是如何来生成的,然后我们会根据返回值做一些不同的操作,如果说我们返回的是一个 T_NEWLINE ,那么我们就可以查找一下我们下一行是一个什么样的语法,下面我们来看一下 lookup_keyword 的实现,我们将下面的内容放到下一期来学习。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值