Linux Command Line 解析

來源:互聯網
上載者:User
 

處理模型Linux kernel 的啟動包括很多組件的初始化和相關配置,這些配置參數一般是通過command line 進行配置的。在進行後續分析之前,先來理解一下command
line 的處理模型: 要處理的對象是一個字串,其中包含了各種配置資訊,通常各個配置之間通過空格進行分離,每個配置的表達形式是如:param=value1,value2或者很簡單就是一個rw 。
那麼kernel 就需要提供對這些參數進行處理的處理函數列表。根據參數的作用以及執行期的先後不同,這些處理函數被定義到不同的段中。針對每一個參數,Kernel 都會到相應的段中尋找相應的處理函數,最終進行各個組件的配置。1 配置格式常見的配置格式如:  
console=ttySAC0,115200 root=nfs nfsroot=192.168.1.9:/source/rootfs initrd=0x10800000,0x14af47
 2 配置方式2.1 Bootloader動態配置由bootloader 進行參數配置,command line 將做為atag_list 的一個節點傳遞到Kernel
。 2.2 Kernel
靜態配置通過make menuconfig 進行配置:運行後配置boot options->Default kernel command string 。該配置將被靜態編譯到Kernel
中,通過變數default_command_line 訪問。3  解析配置3.1 相關定義根據執行的先後順序,可以將處理函數分為三個大類,他們分別存在於下面三個段中(參考top/arch/arm/kernel/vmlinux.lds ): 
__setup_start = .; *(.init.setup) __setup_end = .;
 __early_begin = .; *(.early_param.init) __early_end = .; __start___param = .; *(__param) __stop___param = .;
 這三個段記憶體儲的不是參數,而是command line 參數所需要的處理函數。3.1.1 .early_param.init段
“.early_param.init ” 所定義的處理相對靠前一些,它所處理的參數例如:initrd= ,cachepolicy= ,nocache
, nowb , ecc= , vmalloc= , mem= ,等等。這些處理函數是通過 __early_param宏來定義的,例如:

static void __init early_initrd(char **p)
{ …… }
__early_param("initrd=", early_initrd);
對於宏 __early_param,可以在top/arch/arm/include/asm/Setup.h 中找到如下定義: 
struct early_params {
    const char *arg;
    void (*fn)(char **p);
};
#define __early_param(name,fn) \
static struct early_params __early_##fn __used \
__attribute__((__section__(".early_param.init"))) = { name, fn }
   3.1.2 .init.setup
 “.init.setup ”定義的處理則要靠後一些,它所處理的參數例如:nfsroot= , ip= ,等等。這些處理函數是通過 __setup宏來定義的,例如:
 
static int __init nfs_root_setup(char *line)
{ …… }
__setup("nfsroot=", nfs_root_setup);
 對於宏 __setup,可以在top/include/linux/Init.h 中看到: 
#define __setup_param(str, unique_id, fn, early) \
    static char __setup_str_##unique_id[] __initdata __aligned(1) = str; \
    static struct obs_kernel_param __setup_##unique_id \
           __used __section(.init.setup) \
           __attribute__((aligned((sizeof(long))))) \
           = { __setup_str_##unique_id, fn, early }

#define __setup(str, fn) \
    __setup_param(str, fn, fn, 0)

/* NOTE: fn is as per module_param, not __setup! Emits warning if fn
 * returns non-zero. */
#define early_param(str, fn) \
    __setup_param(str, fn, fn, 1)

 注意看的話,可以看到還有一個宏 early_param
,它與宏 __setup的定義相似,只不過最後一個宏參數是1 而不是0 。1
表示需要提前處理的參數。3.1.3 __param
段這個段中儲存的是build-in 類型module 的配置參數。該宏直接用來修飾需要的變數。3.2  解析 3.2.1
相關變數 相關的變數包括: default_command_line
儲存memuconfig 配置的參數,如果bootloader 傳入了命令列參數,那麼這個新的配置將被更新到該變數中。 boot_command_line
存在於.init.data 段。最初是default_command_line 的拷貝。 command_line
存在於.init.data 段。在parse_cmdline() 中被賦值,資料來源是default_command_line 。 saved_command_line
用於儲存沒有處理過的命令列參數,是boot_caommand_line 的拷貝。 static_command_line
是command_line 的拷貝。3.2.2
主要函數 函數名稱:parse_cmdline() 操作資料:default_command_line函數列表:
.early_param.init 段(在__early_begin 和__early_end 之間)。 函數功能: 依據函數列表對default_command_line 中的參數進行處理。   函數名稱:parse_early_param() 操作資料:boot_command_line函數列表:
.init.setup 段中(__setup_start 和__setup_end 之間),主要是通過宏 early_param定義的部分。 函數功能: 依據函數列表對boot_command_line 中的參數進行處理。注意parse_one() 的第四個入參是0 ,而且第五個參數是NULL 。這裡沒有給出參數隊列,不會對boot_command_line
的每個參數在參數隊列中進行對比尋找,而是直接在do_early_param() 中進行條件判斷,如果滿足下面的條件,那麼對該參數進行對應的操作: 

if ((p->early && strcmp(param, p->str) == 0) ||
                  (strcmp(param, "console") == 0 &&
                   strcmp(p->str, "earlycon") == 0)
              )
   函數名稱:parse_args() 操作資料:static_command_line函數列表:
__param 段(__start___param 和__stop___param 之間)。 函數功能: 該操作將依據函數列表,對static_command_line 中的參數進行相應的操作。這個操作在parse_one() 的第一部分程式碼完成: 

for (i = 0; i < num_params; i++) {
          if (parameq(param, params[i].name)) {
                 DEBUGP("They are equal! Calling %p\n",
                        params[i].set);
                 return params[i].set(val, &params[i]);
          }
   }
 接下來對於不被這個列表所支援的參數,將在unknown_bootoption() 中進行處理。在unknown_bootoption() 中主要是obsolete_checksetup()
的操作。    函數名稱:obsolete_checksetup() 操作資料:static_command_line函數列表:
.init.setup 段中(__setup_start 和__setup_end 之間),主要是通過宏 __setup定義的部分。 函數功能: 該操作將依據函數列表,對static_command_line 中的參數進行相應的操作。如果是在parse_early_param() 中已經處理的操作,那麼這裡不再處理;如果是尋找到的條目中沒有操作函數,那麼這表示是過時的資料定義(有些早期的代碼,沒有定義這個函數);如果不是以上兩種情形,那麼利用找到的函數對參數進行處理。3.2.3圖示
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.