busybox初探

一、busybox是什麼?

     (1)busybox是Linux上的一個應用程序(application)。

     (2)它整合了許多Linux上常用的工具和命, 如rm, ls, gzip, tftp等。對於這些工具和命令,busybox中的實現可能不是最全的,但卻是最常用的,因此它的特點就是短小精悍特別適合對尺寸很敏感的嵌入式系統

     (3)busybox的官方網站是http://www.busybox.net/,在這裏你可以找到與busybox相關的所有資料。

 

二、busybox的下載

       最新的busybox的源碼更新都可以在http://www.busybox.net/downloads/ 裏面找到。

 

三、Busybox目錄結構簡介

 

四、Busybox中最重要的程序:init進程

(1)Busybox init在嵌入式系統中的應用

         大家都知道init進程是由內核啓動的第一個(也是唯一一個)用戶進程(進程ID爲1),init進程根據配置文件決定啓動哪些程序,例如:執行某些腳本、啓動shell或運行用戶程序等等。

         由於BusyBox自身的一些特點,BusyBox init非常適合在嵌入式系統開發中使用,被譽爲“嵌入式linux的瑞士軍刀”。 在嵌入式系統中常使用的也是Busybox集成的init程序,通過定製可以將其做得非常精煉。

(2)init的執行流程

        移植uboot的目的是啓動內核,啓動內核的目的是運行應用程序,從內核的啓動流程中可以知道內核啓動的第一個應用程序就是busybox裏的/sbin/init進程!
        但是我們的最終目的不是啓動init進程,而是運行客戶的程序!
        那麼init進程是如何選擇性的運行客戶的程序呢?我們猜測init進程肯定需要:
      (1) 讀取一個配置文件
      (2) 解析該配置文件
      (3) 根據配置文件執行客戶的程序

 

接下來分析busybox中init程序的源碼,看看我們上述猜測的流程是否相同。

由於init_main很長,所以我們簡化其代碼,就流程中的幾個重點部分代碼進行分析:

init_main()在init/init.c的中,以下按照重點代碼順序依次分析:

 

1.在設置信號後,初始化/dev/console

console_init();

 

2.讀取配置文件,並解析它

if (argv[1]
&& (strcmp(argv[1], "single") == 0 || strcmp(argv[1], "-s") == 0 || LONE_CHAR(argv[1], '1'))
	) {
		new_init_action(RESPAWN, bb_default_login_shell, "");
	  }
     else {
		parse_inittab();
	  }

 因爲內核啓動/sbin/init是沒有傳如何參數,所以上述程序進入parse_inittab()函數。

 

 

我們進入到parse_inittab()函數:

首先遇到的是這段程序: 

parser_t *parser = config_open2("/etc/inittab", fopen_for_read);

由此可以知道init進程讀取的配置文件就是/etc/inittab,busybox中的inittab文件中規定了/etc/inittab內容的填寫格式如下: 

<id>:<runlevel>:<action>:<process>
Id:id會加上一個/dev前綴作爲一個控制終端(stdin,stdout,stderr)
Runlevel:忽略
Action:執行的時機,包括SYSINIT,WAIT,ONCE, RESPAWN,ASKFIRST等
Process:要執行的應用程序或者腳本

 

接着繼續分析 parse_inittab()剩餘的程序:

if (parser == NULL)
{
     new_init_action(SYSINIT, INIT_SCRIPT, "");
     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);
     new_init_action(CTRLALTDEL, "reboot", "");
     new_init_action(SHUTDOWN, "umount -a -r", "");
     new_init_action(SHUTDOWN, "swapoff -a", "");
     new_init_action(RESTART, "init", "");
		
     return;
}

如果配置文件/etc/inittab不存在的話則執行if語句,也就是說如果沒/etc/inittab的話init進程會直接調用new_init_action來構造默認配置項,根據if語句裏的內容,我們可以反推出等效的/etc/inittab的內容如下: 

::SYSINIT:/etc/init.d/rcS
::ASKFIRST:-/bin/ah
tty2:: ASKFIRST:-/bin/sh
tty3:: ASKFIRST:-/bin/sh
tty4:: ASKFIRST:-/bin/sh
::CTRLALTDEL:reboot
::SHUTDOWN:umount -a –r
::RESTART:init

這裏 new_init_action()函數是配置的核心,其主要作用是將/etc/inittab裏的每一條配置項做成一個init_action結構體並添加到具有相同執行時機的init_action_list中去,最終將它們連接成單鏈表。

也就是說解析/etc/inittab這個配置文件就是爲了把各配置項添加到對應的init_action_list中去。

到這裏,parse_inittab()這個函數就結束了,我們繼續回到init_main()這個函數的分析。

 

 

3.運行parse_inittab()幫我們添加到init_action_list中的程序或腳本

    run_actions(SYSINIT);
    run_actions(WAIT);
    run_actions(ONCE);
    while (1) 
    {
        run_actions(RESPAWN);
        run_actions(ASKFIRST);
    }

run_actions爲運行一類程序或腳本,這裏的一類就是按照執行時機來分類的。

 

總結上述對於init_main()函數的分析,我們看到init進程的執行流程與我們猜測的基本相同。init進程起來後,首先會去讀取/etc/inittab配置文件,如果沒/etc/inittab的話init進程會直接調用new_init_action來構造默認配置項;然後解析這個配置文件,將/etc/inittab裏的每一條配置項做成一個init_action結構體並添加到具有相同執行時機的init_action_list;最後,根據init_action_list來運行其中的程序和腳本。

 

 

五、busybox的配置、編譯和安裝

在busybox的INSTALL文件已經說明我們應該如何配置、編譯和安裝busybox。

Building:
=========

The BusyBox build process is similar to the Linux kernel build:

  make menuconfig     # This creates a file called ".config"
  make                # This creates the "busybox" executable
  make install        # or make CONFIG_PREFIX=/path/from/root install

The full list of configuration and install options is available by typing:

  make help

文件中寫的很明確,編譯busybox和編譯linux kernel差不多。即首先要make menuconfig生成配置文件.config。然後make生成busybox可執行文件。最後make install安裝busybox。

第一步,執行 make menuconfig: 

執行過後會出現圖形界面,這方便了我們對busybox的配置,這裏我們只需要手動選擇需要編譯安裝的項目,最後進行保存就可以了。最後Exit,save即可。

第二步,執行make命令生成可執行busybox文件。

第三步,make install進行安裝。

這樣,經過簡單的配置、編譯和安裝我們便可以使用busybox了。

 

關於busybox的配置、編譯和安裝可以詳細參考博客:     busybox詳解 中的構造自己的根文件系統部分。

 

六、關於busybox的使用

busybox的使用很簡單,有以下三種方式:

(1)   busybox後直接跟命令,如

       busybox ls

       busybox tftp

(2)   直接將busybox重命名,如

       cp busybox tftp

       cp busybox tar

       然後再執行tftp, tar  

(3)  創建符號鏈接(symbolic link), 如

       ln -s busybox rm

       ln -s busybox mount

       然後就可以執行rm,mount等

 

 

 

 

 

 

 

 

 

 

              

 

 

 

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