The role of a busybox
- The role of busybox: essentially an application program, which implements various commands such as ls/cp sent by the shell.
shell发送ls指令==执行busybox ls指令
Verify the above conclusion: the
root directory system bin folder: /bin stores binary executable files (ls, cat, mkdir, etc.), commonly used commands are generally here.
As can be seen from the figure above: the ls instruction is actually linked to the busybox file
- The role of busybox: the initial process /sbin/init executed by the linux kernel is also implemented by busybox.
Two busybox source code analysis 1
Note: Take cp command and init command as examples
- The cp instruction corresponds to the cp.c file, which contains the cp_main() sub-function
- init program: the init.c file is as shown in the figure below. The init_main program is executed when the linux kernel calls sbin/init.
Three busybox source code analysis 2-init program analysis
The role of the init program: the ultimate goal to start the user program
设计思路:
(1)读取配置文件
(2)解析配置文件
(3)根据配置文件执行用户程序
Source code analysis of init program:
busybox-> init_main
parse_inittab();
file = fopen(INITTAB, "r"); //(1)打开配置文件etc/inittab
//(2)解析文件过程;
new_init_action(a->action, command, id);//(3)根据配置文件执行用户程序
//a->action:inittab配置文件<action>
//command:inittab配置文件<process>
//id:inittab配置文件格式<id>
run_actions(SYSINIT);
waitfor(a, 0);//执行应用程序,等待它执行完毕
delete_init_action(a);把SYSINIT对应的应用程序从链表中删除,即只允许执行一次
run_actions(WAIT);
run_actions(ONCE);
while(1){
...
}
inittab配置文件格式:
<id>:<runlevels>:<action>:<process>
<id>=> /dev/id,用作终端:stdin,stdout,stderr:printf,scanf,err
<runlevels>:=>忽略
<action>:执行时机
有效取值: sysinit, respawn, askfirst, wait, once,restart, ctrlaltdel, and shutdown.
<process>:应用程序或者脚本
- Key signal processing: for example, specific processing will be performed when pressing the ctrl+alt+del key
- There is no parameter output when linux calls this program, so argc=1 is executed
parse_inittab();
Four busybox source code analysis 3-analysis function parse_inittab()
- Enter the
parse_inittab();
function for analysis:
(1) Open the configuration fileINITTAB
INITTAB file storage address, see the figure below.
INITTAB configuration file format: (see busybox-1.7.0\examples\inittab)
# <id>:<runlevels>:<action>:<process>
The information contained in the INITTAB configuration file: specify which user program; when the program will be executed;
(2) If there is no default configuration file, the following processing will be performed
(3) parse the INITTAB file:
a. If the # character or the carriage return character appears, just ignore it The entire line
b. Add the id string in front /dev/
, and finally execute the LINE846 line of code: enter the new_init_action();
function
- Analysis
new_init_action(int action, const char *command, const char *cons);
function:
takenew_init_action(ASKFIRST, bb_default_login_shell, VC_2);
thatnew_init_action(0x004, "-/bin/sh", "/dev/vc/2");
as an example to analyze the
following table is the key! ! ! ! ! !
例子中传入的参数 参数含义 函数声明原型
ASKFIRST:0x004------------------------>inittab配置文件<action>调用时机------------>int action
bb_default_login_shell:"-/bin/sh"----->inittab配置文件<process>应用程序或者脚本---->const char *command
VC_2:"/dev/tty2"---------------------->inittab配置文件格式<id>用作终端------------->const char *cons
Design idea: Create an init_action structure and initialize it with the passed parameters; put the structure into the init_action_list linked list
. The init_action
structure definition is as follows:
struct init_action *next;为链表用。
action : 执行时机
pid : 进程号
command : 对应执行程序 (-/bin/sh)
terminnal : 对应终端(/dev/tty2)
First, analyze the code LINE705~LINE716. This function traverses all the data in the linked list, and checks whether there is a certain data in the linked list and has the same parameters as the incoming action, *command, and *cons. If there is, return directly; when
entering this function for the first time, the linked list is empty, so this condition is not established.
Secondly, analyze lines LINE718~LINE730 of the code,
LINE718:给结构体指针new_action分配了一个空间和位置;
LINE719~LINE723:如果init_action_list链表为空,则直接放置在首地址上,如果非空则放置在最末尾
LINE724~LINE726:把本次输入的参数存储进入结构体
- According to the conclusion of the analysis in the previous section, the
new_init_action()
function will add the incoming parameters to the linked list. Then, if you need to pass some default configuration parameters, you can call this function repeatedly. - Back to
parse_inittab();
the code of the function : if there is a default configuration file, the subsequent operations will be parsed, and if there is no default configuration file, the code will also provide the default configuration, as shown in the code below:
- According to the above code, the default configuration file is
deduced according to the new_init_action() function prototype andinit_tab
description file:
'action’有效取值: sysinit, respawn, askfirst, wait, once,restart, ctrlaltdel, and shutdown.
Inittab configuration file format: the <id>:<runlevels>:<action>:<process>
default value of the configuration file:
::CTRLALTDEL:reboot
::SHUTDOWN:umount -a -r
::RESTART:init
::ASKFIRST:-/bin/sh
/dev/tty2::ASKFIRST:-/bin/sh
/dev/tty3::ASKFIRST:-/bin/sh
/dev/tty4::ASKFIRST:-/bin/sh
::SYSINIT:/etc/init.d/rcS
Five busybox source code analysis 4- continue init program analysis
- The remaining steps are abbreviated as follows:
run_actions(SYSINIT);
run_actions(WAIT);
run_actions(ONCE);
while (1)
{
run_actions(RESPAWN);
if (a->pid == 0)
a->pid = run(a);
run_actions(ASKFIRST);
if (a->pid == 0)
a->pid = run(a);
打印Please press Enter to activate this console.
等待回车按键
创建进程
wpid = wait(NULL); //等待以上两个子进程退出
while (wpid > 0)
a->pid = 0; //哪个子进程退出,就设置其pid=0,然后继续执行
}
- Analysis function
run_actions(SYSINIT);/run_actions(WAIT);
LINE533: The init_action_list linked list is a linked list with several default initial values just added to the new_init_action function. At this time, the linked list has initialized values;
LINE535: Traverse each value in the linked list, if it is consistent with the passed parameter "action", perform the following operations
LINE539~LINE541: The
first parameter passed in is SYSINIT, then execute
LINE540waitfor(a, 0);//execute the application and wait for it to complete;
delete_init_action(a); delete the application corresponding to SYSINIT from the linked list, that is, only Allow to execute once
//------------------------------------------------ ----------------------------------------
Insert
analysis: function waitfor()
LINE513: execute Application a run(a)
-create process subprocess
LINE514~LINE524: wait for the end of the subprocess execution
//----------------------------------------------------------------------------------------//
- Analysis function
run_actions(ONCE);
direct execution
LINE543: run(a); Do not wait for execution to complete
LINE544: delete_init_action(a);
4. Analysis function run_actions(RESPAWN);run_actions(ASKFIRST);
Refer to the figure above and execute LINE548~LINE549 directly: only when the process number pid is 0 will be executed
/* Only run stuff with pid==0. If they have* a pid, that means it is still running */
if (a->pid == 0)
a->pid = run(a);
- Well
RESPAWN
, andASKFIRST
what difference does it make? Need analysisrun()
function
LINE464: If it is ASKFIRST, then the printed information
LINE478: Wait for the console to enter and press Enter, otherwise there will be an endless loop here
LINE500: Create a child process
Six busybox source code analysis 4-ctrlaltdel, and shutdown.
Above we know that the allowed values of action sysinit, respawn, askfirst, wait, once,restart
are all reflected in the source code, and whether ctrlaltdel, shutdown
they appear in the code.
action的合理值
action: Valid actions include: sysinit, respawn, askfirst, wait, once,restart, ctrlaltdel, shutdown.
-
Back to the
init_main
function, as shown in the figure below.
When the keyboard presses "crtl+alt+del", aSIGINT
signal is sent to the
kernel ; the kernel code executes the function when the signal isinit_main
received .SIGINT
ctrlaltdel_signal
-
Analysis
ctrlaltdel_signal
function
Enter the run_actions(CTRLALTDEL)
function, there is analysis on the function.
Therefore, when the keyboard presses "crtl+alt+del", the kernel executes the CTRLALTDEL
program.
For other signals, the kernel will 1.signal
execute the relevant code in the corresponding program.
Seven items required by the smallest root file system (Note 4.1 4.2 Summary)
(Required for init process)
- Open the terminal: /dev/console, /dev/NULL
If the id (standard input, output and standard error) in the inittab format is not set, it will be located in /dev/NULL. - /sbin/init (init program): It is busybox itself.
- /etc/inittab: configuration file is required.
If the configuration file specifies certain applications or execution scripts-these must exist, there will be defaults if they do not exist. - Libraries required by the application (printf, fopen, fwrite and other functions require library functions).