Linux内核参数传递Tag
???????????????????+-----------+
????????????????????tag_header
???????????????????+-----------+
??????????????????? tag_xxx
???????????????????+-----------+
?
其中tag_header為tag頭,表明tag_xxx的類型和大小,之所以要標(biāo)識(shí)tag_xxx的類型是因?yàn)椴煌膖ag需要不同的處理函數(shù)(下文講tagtable的時(shí)候會(huì)分析到)。tag_header的結(jié)構(gòu)為
| struct tag_header |
size表示tag的結(jié)構(gòu)大小,tag為表示tag類型的常量。這個(gè)靜態(tài)的鏈表必須以tag_header.tag = ATAG_CORE開始,并以tag_header.tag = ATAG_NONE結(jié)束。由于不同的tag所使用的格式可能不盡相同,所以內(nèi)核又定義了一個(gè)結(jié)構(gòu)tagtable來(lái)把tag和相應(yīng)的操作函數(shù)關(guān)聯(lián)起來(lái)
| struct tagtable |
?
?
其中tag為標(biāo)識(shí)入ATAG_NONE,ATAG_CORE等。parse為處理函數(shù)。Linux內(nèi)核將tagtable也組成了一個(gè)靜態(tài)的鏈表放入.taglist.init節(jié)中,這是通過__tagtable宏來(lái)實(shí)現(xiàn)的| #define __tag __attribute_used__ __attribute__((__section__ (“.taglist.init”))) |
以處理命令行參數(shù)為例:
| static int __init parse_tag_cmdline(const struct tag* tag) |
?
?
可以看到parse_tag_cmdline將命令行參數(shù)拷貝到default_command_line里,__tagtable將ATAG_CMDLINE和parse_tag_cmdline掛鉤。
以上已經(jīng)分析了內(nèi)核和tag相關(guān)的兩個(gè)重要結(jié)構(gòu)。現(xiàn)在分析具體的實(shí)現(xiàn)。內(nèi)核中定義了一些默認(rèn)的tags
| static struct init_tags |
上述結(jié)構(gòu)中一個(gè)tag_header和tag_xxx形成了tag的完整描述,tag_size返回tag_head和tag_xxx的總大小,在tag_size中我們要注意的是u32*指針加1地址值實(shí)際上地址加了4
#define tag_next(t) ((struct tag*)((u32*)(t)+(t)->hdr.size))
#define tag_size(type) ((sizeof(struct tag_header)+sizeof(struct type)) >> 2
tag_size實(shí)際上計(jì)算的是(tag_head+tag_xxx)/4。經(jīng)過進(jìn)一步的分析還發(fā)現(xiàn)每個(gè)tag在內(nèi)存中的大小并不是相同的,這一點(diǎn)可以從tag_next看出,tag_next只是將指針移到了下一個(gè)tag的tag_header處,這種內(nèi)存布局更加緊湊。對(duì)tag的處理代碼在arch/arm/setup.c setup_arch里面。以下是一部分的關(guān)鍵代碼
| struct tag *tags = (struct tag*)&init_tags; //tags指向默認(rèn)的tag鏈表 |
*注:2.6.18內(nèi)核smdk2410的meminfo沒有設(shè)置nr_banks,所以必須在內(nèi)核的啟動(dòng)參數(shù)里面?zhèn)鬟fmem=”memory size”@”memory base address”,否則系統(tǒng)識(shí)別內(nèi)存錯(cuò)誤,這點(diǎn)從系統(tǒng)的啟動(dòng)信息就可以看出來(lái),而且在加載initrd的時(shí)候也會(huì)遇到內(nèi)存溢出的錯(cuò)誤
?
?
| static void __init parse_tags(const struct tag* t) |
parse_tags遍歷tag鏈表調(diào)用parse_tag對(duì)tag進(jìn)行處理。parse_tags在tabtable中尋找tag的處理函數(shù)(通過tag_header結(jié)構(gòu)中的tag)。
總結(jié)
以上是生活随笔為你收集整理的Linux内核参数传递Tag的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第一次办信用卡被拒绝怎么办
- 下一篇: Linux下,sqlite简单实例