01_busybox之init_main分析

回顧:
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庫實現
    

}


 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章