The parsing of Init.rc is done in Parse_config (): [SYSTEM/CORE/INIT/INIT_PARSER.C]. The parsing occurs at which stage of the Init process, as in the "Android init process Initiation Process Analysis".
First, the analytical process
1. Scanning the token in init.rc
Locate the file end eof/text text/New line newline, where the space ', ' \ t ', ' \ R ' will be ignored, #开头的行也被忽略掉;
For text, the spaces ', ' \ t ', ' \ R ', ' \ n ' are the end flags of text.
2. For each text token, add to the args[] array
3. When encountering a new line (' \ n '), use args[0] to retrieve the matching keyword by lookup_keyword ();
1 (on and service), invoke Parse_new_section () Resolution:
-On the on section, Invoke Parse_action () and set the parse function Parse_line to Parse_line_action ()
-On Service section, call Parse_service (), and set the parse function Parse_line as Parse_line_service ()
2 call Parse_line () for other keyword lines (not on or at the beginning of the service, that is, no toggle section)
Is
-Invoke Parse_line_action () parsing for the command line within the on section;
-Invoke Parse_line_service () resolution for the command line within the service section.
Key data type prototypes and key data definitions
Definition of 2.1 token
[CPP]
#defineT_EOF 0
#defineT_TEXT 1
#defineT_NEWLINE 2
#defineT_EOF 0
#defineT_TEXT 1
#defineT_NEWLINE 2
2.2 Keyword Definitions
[CPP]
KEYWORD (capability, OPTION, 0, 0)
KEYWORD (ChDir, COMMAND, 1, Do_chdir)
KEYWORD (Chroot, COMMAND, 1, Do_chroot)
KEYWORD (class, OPTION, 0, 0)
KEYWORD (Class_start, COMMAND, 1,do_class_start)
KEYWORD (Class_stop, COMMAND, 1, do_class_stop)
KEYWORD (console, OPTION, 0, 0)
KEYWORD (Critical, OPTION, 0, 0)
KEYWORD (Disabled, OPTION, 0, 0)
KEYWORD (domainname, COMMAND, 1, Do_domainname)
KEYWORD (exec, COMMAND, 1, do_exec)
KEYWORD (Export, COMMAND, 2, Do_export)
KEYWORD (group, OPTION, 0, 0)
KEYWORD (hostname, COMMAND, 1, Do_hostname)
KEYWORD (Ifup, COMMAND, 1, do_ifup)
KEYWORD (Insmod, COMMAND, 1, Do_insmod)
KEYWORD (Import, COMMAND, 1, Do_import)
KEYWORD (keycodes, OPTION, 0, 0)
KEYWORD (mkdir, COMMAND, 1, Do_mkdir)
KEYWORD (Mount, COMMAND, 3, Do_mount)
KEYWORD (on, section, 0, 0)
KEYWORD (oneshot, OPTION, 0, 0)
KEYWORD (Onrestart, OPTION, 0, 0)
KEYWORD (restart, COMMAND, 1, Do_restart)
KEYWORD (service, section, 0, 0)
KEYWORD (Setenv, OPTION, 2, 0)
KEYWORD (Setkey, COMMAND, 0, Do_setkey)
KEYWORD (SetProp, COMMAND, 2, Do_setprop)
KEYWORD (Setrlimit, COMMAND, 3, Do_setrlimit)
KEYWORD (socket, OPTION, 0, 0)
KEYWORD (Start, COMMAND, 1, Do_start)
KEYWORD (Stop, COMMAND, 1, do_stop)
KEYWORD (Trigger, COMMAND, 1, Do_trigger)
KEYWORD (Symlink, COMMAND, 1, Do_symlink)
KEYWORD (Sysclktz, COMMAND, 1, Do_sysclktz)
KEYWORD (user, OPTION, 0, 0)
KEYWORD (Wait, COMMAND, 1, do_wait)
KEYWORD (Write, COMMAND, 2, Do_write)
KEYWORD (Copy, COMMAND, 2, do_copy)
KEYWORD (Chown, COMMAND, 2, Do_chown)
KEYWORD (chmod, COMMAND, 2, Do_chmod)
KEYWORD (LogLevel, COMMAND, 1, Do_loglevel)
KEYWORD (Ioprio, OPTION, 0, 0)
KEYWORD (capability, OPTION, 0, 0)
KEYWORD (ChDir, COMMAND, 1, Do_chdir)
KEYWORD (Chroot, COMMAND, 1, Do_chroot)
KEYWORD (class, OPTION, 0, 0)
KEYWORD (Class_start, COMMAND, 1,do_class_start)
KEYWORD (Class_stop, COMMAND, 1, do_class_stop)
KEYWORD (console, OPTION, 0, 0)
KEYWORD (Critical, OPTION, 0, 0)
KEYWORD (Disabled, OPTION, 0, 0)
KEYWORD (domainname, COMMAND, 1, Do_domainname)
KEYWORD (exec, COMMAND, 1, do_exec)
KEYWORD (Export, COMMAND, 2, Do_export)
KEYWORD (group, OPTION, 0, 0)
KEYWORD (hostname, COMMAND, 1, Do_hostname)
KEYWORD (Ifup, COMMAND, 1, do_ifup)
KEYWORD (Insmod, COMMAND, 1, Do_insmod)
KEYWORD (Import, COMMAND, 1, Do_import)
KEYWORD (keycodes, OPTION, 0, 0)
KEYWORD (mkdir, COMMAND, 1, Do_mkdir)
KEYWORD (Mount, COMMAND, 3, Do_mount)
KEYWORD (on, section, 0, 0)
KEYWORD (oneshot, OPTION, 0, 0)
KEYWORD (Onrestart, OPTION, 0, 0)
KEYWORD (restart, COMMAND, 1, Do_restart)
KEYWORD (service, section, 0, 0)
KEYWORD (Setenv, OPTION, 2, 0)
KEYWORD (Setkey, COMMAND, 0, Do_setkey)
KEYWORD (SetProp, COMMAND, 2, Do_setprop)
KEYWORD (Setrlimit, COMMAND, 3, Do_setrlimit)
KEYWORD (socket, OPTION, 0, 0)
KEYWORD (Start, COMMAND, 1, Do_start)
KEYWORD (Stop, COMMAND, 1, do_stop)
KEYWORD (Trigger, COMMAND, 1, Do_trigger)
KEYWORD (Symlink, COMMAND, 1, Do_symlink)
KEYWORD (Sysclktz, COMMAND, 1, Do_sysclktz)
KEYWORD (user, OPTION, 0, 0)
KEYWORD (Wait, COMMAND, 1, do_wait)
KEYWORD (Write, COMMAND, 2, Do_write)
KEYWORD (Copy, COMMAND, 2, do_copy)
KEYWORD (Chown, COMMAND, 2, Do_chown)
KEYWORD (chmod, COMMAND, 2, Do_chmod)
KEYWORD (LogLevel, COMMAND, 1, Do_loglevel)
KEYWORD (Ioprio, OPTION, 0, 0)
2.3 struct action and struct command
[CPP]
Copy Code code as follows:
struct Action {
/* node in list the all actions * *
struct ListNode alist;
/* node in the queue of pending actions*/
struct ListNode qlist;
/* node in list's actions for Atrigger * *
struct ListNode tlist;
unsigned hash;
const char *name;
struct ListNode commands;
struct command *current;
};
struct Action {
/* node in list the all actions * *
struct ListNode alist;
/* node in the queue of pending actions*/
struct ListNode qlist;
/* node in list's actions for Atrigger * *
struct ListNode tlist;
unsigned hash;
const char *name;
struct ListNode commands;
struct command *current;
};
[CPP]
View Plaincopyprint?
Copy Code code as follows:
struct command
{
/* List of commands in a action * *
struct ListNode clist;
Int (*func) (int nargs, char **args);
int Nargs;
Char *args[1];
};
struct command
{
/* List of commands in a action * *
struct ListNode clist;
Int (*func) (int nargs, char **args);
int Nargs;
Char *args[1];
};
2.4 List Action_list and Action_queue
Action_list
When parsing init.rc, the on action is encountered by Act->alist join;
Queue_builtin_action () composes the executed function into the command, creates the action, and hangs on the action_list.
Action_queue
Execute Action_for_each_trigger () and join by Act->qlist;
Queue_builtin_action () composes the executed function into the command, creates the action, hangs on the action_list, and appends it to the Action_queue's tail.
Third, the analysis of the action
Combined with the INIT process and the init.rc of the previous explanation, this paper sums up the analysis of the action of Init on init.rc.
An analysis of the action in the section of 3.1 on
When parsing to the new on Section call Parse_action (), the struct action *act is requested, setting: 1.3.1
1) Act->name is the name on the section (e.g. boot/fs/);
2 Initialize list act->commands;
3) Add act->alist to the action_list end of the column
In this way, the action is created and added to the action_list.
3.2 On the command in section action
Call Parse_line_action () on the command in the action in section.
1 Find the key word, check whether the command, the number of parameters is correct
2) apply for struct command *cmd
-Cmd->func is obtained from the keyword table;
-Set the number of parameters to Cmd->nargs, copy parameters to cmd->args;
-Add cmd->clist to the act->commands end of the column
In this way, the command is added to the action.
3.3 Action_list The action in the Action_queue.
Action_for_each_trigger () Appends the action in the queue action_list to the action_queue's tail;
Queue_builtin_action () composes the executed function into the command, creates the action, hangs on the action_list, and appends it to the Action_queue's tail.
3.4 Execution of the command
Init's infinite Loop Execute_one_command (): system/core/init/init.c
1) removing structaction *act from action_queue and assigning it to cur_action;
2) obtain struct command * from cur_action to Cur_command;
3) Executive Cur_command->func (Cur_command->nargs, Cur_command->args)
The above steps 1, 2 & 3 are executed at one time, 4 is infinite loop execution, remove action,action from action_queue to obtain command, and execute command.
Iv. Summary of Init.rc Grammar
There is a description of init.rc grammar in the System/core/init/readme. Before the author did not analyze the init source code, but also read this readme file, but the definition of some concepts are not very clear. Now after analyzing the init.rc parsing, try to do some sorting on the init.rc grammar.
1. #开头的行也被忽略掉, for annotations;
2. ', ' \ t ', ' \ R ' will be ignored, so the attribute contains spaces, the following will not be recognized, each action in front of the command indentation and no grammatical requirements, but easy to read;
3. ' \ n ' is the symbol of line change, init syntax, the beginning of the new resolution is based on the start of a new line, is a progressive scan resolution;
4. Some concepts: Section/action/command/trigger
-Init.rc, Encounter on<trigger> or service <name> <pathname> [<argument>]* Line, marking the beginning of a new section [see 2.2 In the keyword definition, the type of section is also only on and service];
-Encountered on <trigger>,trigger is the trigger condition, the timing of the occurrence. It can be early-init/init/early-fs/fs/post-fs/early-boot/boot, or it can be property:<name>=<value>., Properties <name> The value is set to <value> when the device-added-<path>/device-removed-<path> device node is added or removed; service-exited-<name When the > service exits.
-On <trigger> occurs, execution action, which is the part behind on<trigger>, can contain multiple command;
-command each line, which command is supported, and look at the keyword Type command in the 2.2 key definition.
The form is as follows:
[CPP]
On <trigger>
<command>
<command>
<command>
On <trigger>
<command>
<command>
<command> This whole is a section; all <command> call action.
Summarize
This paper analyzes the basic syntax of INIT.RC, focuses on the analysis of section, service analysis and property support in the follow-up topics discussed in detail.