回顧:
U-boot最終目的:啓動內核
內核最終目的:啓動應用程序,(init進程,通過sbin/init或其它)
init程序包括以下內容:
(1)讀取配置文件
(2)解析配置文件
(3)根據配置文件,啓動/執行用戶程序
配置文件中包括:
(1)指定用戶程序
(2)何時執行
/////////////////////////////////////////////////////////////////////////////////////////
busybox-> init_main
parse_inittab // 解析init表
file = fopen(INITTAB, "r"); // 打開配置文件 "/etc/inittab"
new_init_action // (1)創建一個init_action結構,內容用上面的內容填充
(2)把這個結構放入init_action_list鏈表
run_actions(SYSINIT); //執行SYSINIT這一類的action,即執行系統初始化
waitfor(a, 0); //執行應用程序,等待它執行完畢
run(a) //創建precess子進程(子進程就是<process> 裏面的指定的程序)
waitpid(runpid, &status, 0); //等待它結束
delete_init_action(a); //把init_action結構在init_action_list鏈表裏刪掉
run_actions(WAIT);
waitfor(a, 0); //執行應用程序,等待它執行完畢
run(a) //創建precess子進程(子進程就是<process> 裏面的指定的程序)
waitpid(runpid, &status, 0); //等待它結束
delete_init_action(a); //把init_action結構在init_action_list鏈表裏刪掉
run_actions(ONCE);
run(a) //創建precess子進程(子進程就是<process> 裏面的指定的程序)
delete_init_action(a); //把init_action結構在init_action_list鏈表裏刪掉
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
等待回車while (read(0, &c, 1) == 1 && c != '\n')
創建子進程
}
wpid = wait(NULL); //等待子進程退出
while (wpid > 0) {
a->pid = 0; //退出後就設置pid=0
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
#define SYSINIT 0x001
#define RESPAWN 0x002
#define ASKFIRST 0x004
#define WAIT 0x008
#define ONCE 0x010
#define CTRLALTDEL 0x020
#define SHUTDOWN 0x040
#define RESTART 0x080
//////////////////////////////////////////////////////////////////////////////////////////////
從默認的new_init_action反推出默認的配置文件(inittab)
/* Reboot on Ctrl-Alt-Del */
new_init_action(CTRLALTDEL, "reboot", "");
/* Umount all filesystems on halt/reboot */
new_init_action(SHUTDOWN, "umount -a -r", "");
/* Swapoff on halt/reboot */
if (ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", "");
/* Prepare to restart init when a HUP is received */
new_init_action(RESTART, "init", "");
/* Askfirst shell on tty1-4 */
new_init_action(ASKFIRST, bb_default_login_shell, "");
new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
new_init_action(ASKFIRST, bb_default_login_shell, VC_3);
new_init_action(ASKFIRST, bb_default_login_shell, VC_4);
/* sysinit */
new_init_action(SYSINIT, INIT_SCRIPT, "");
分析如下
# INITTAB的格式,如下
# <id>:<runlevels>:<action>:<process> (存在busybox-1.7.0\examples\inittab中)
# id => /dev/id, 用於中斷:stdin, stdout, stderr: pritf, scanf, err
# runlevels: 忽略
# action:執行時機,指示何時執行
# <action>: Valid actions include: sysinit(系統初始化), respawn, askfirst, wait, once,
# restart, ctrlaltdel, and shutdown.
# process:執行程序或腳本
進而將
/* Reboot on Ctrl-Alt-Del */
new_init_action(CTRLALTDEL, "reboot", "");
/* Umount all filesystems on halt/reboot */
new_init_action(SHUTDOWN, "umount -a -r", "");
/* Swapoff on halt/reboot */
if (ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", "");
/* Prepare to restart init when a HUP is received */
new_init_action(RESTART, "init", "");
/* Askfirst shell on tty1-4 */
new_init_action(ASKFIRST, bb_default_login_shell, "");
new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
new_init_action(ASKFIRST, bb_default_login_shell, VC_3);
new_init_action(ASKFIRST, bb_default_login_shell, VC_4);
/* sysinit */
new_init_action(SYSINIT, INIT_SCRIPT, "");
改寫成下面內容
# ::CTRLALTDEL:reboot
# ::SHUTDOWN:umount -a -r
# ::RESTART:init
# ::ASKFIRST:bb_default_login_shell
# tty2::ASKFIRST:bb_default_login_shell
# tty3::ASKFIRST:bb_default_login_shell
# tty4::ASKFIRST:bb_default_login_shell
# ::SYSINIT:/etc/init.d/rcS
////////////////////////////////////////////////////////////////////////////////////////
分析:new_init_action
例如,
new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
static void new_init_action(int action, const char *command, const char *cons)
分析如下,
new_init_action(ASKFIRST, "-/bin/sh", "/dev/tty2");
static void new_init_action(int action, const char *command, const char *cons)
# action process id
new_init_action做的事情如下:
(1)創建一個init_action結構,內容用上面的內容填充
(2)把這個結構放入init_action_list鏈表
///////////////////////////////////////////////////////////////////////////////////////////
分析INITTAB的格式
<id>:<runlevels>:<action>:<process> (存在busybox-1.7.0\examples\inittab中)
其中,
id => /dev/id, 用於中斷:stdin, stdout, stderr: pritf, scanf, err
runlevels: 忽略
action:執行時機,指示何時執行
process:執行程序或腳本
//////////////////////////////////////////////////////////////////////////////////////////////
回顧:
最小的根文件系統必須要有下面這幾項:
(1)dev/console 和 dev/null
(2)init應用程序(來源於bustbox)
(3)init程序運行時,要讀配置文件 /etc/inittab
(4)配置文件指定的應用程序
(5)C庫
etc/inittab
配置文件裏指定的應用程序
庫
init本身,即busybox
///////////////////////////////////////////////////////////////////////////////////////////////
下面寫個簡單的應用程序
int main()
{
printf("hell, world!\n"); // printf 由C庫實現
fopen(); // fopen 由C庫實現
fwrite(); // fwrite 由C庫實現
}