日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

Linux内核参数传递Tag

發(fā)布時(shí)間:2023/12/10 linux 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux内核参数传递Tag 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
在2.4(具體哪個(gè)版本記不清了)以后的Linux內(nèi)核中引入了一種新的向內(nèi)核傳遞參數(shù)的方法tag標(biāo)記。內(nèi)核參數(shù)通過一個(gè)靜態(tài)的tag鏈表在啟動(dòng)的時(shí)候傳遞到內(nèi)核。每個(gè)tag的結(jié)構(gòu)為

???????????????????+-----------+

????????????????????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
{
????int size;
????int tag;
}

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
{
???????u32 tag;
???????int (*parse)(const struct tag*);
}

?

?

其中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”)))

#define __tagble(tag,fn) static struct tagtable __tagtable_##fn __tag = {tag, fn}

以處理命令行參數(shù)為例:

static int __init parse_tag_cmdline(const struct tag* tag)
{
????strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
}
__tagtable(ATAG_CMDLINE, parse_tag_cmdline)

?

?

可以看到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
{
???????struct tag_header hdr1;
???????struct tag_core core;
???????struct tag_header hdr2;
???????struct tag_mem32 mem;
???????struct tag_header hdr3;
}init_tags __initdata = {
???????{ tag_size(tag_core), ATAG_CORE },
???????{ 1, PAGE_SIZE, 0xff },
???????{ tag_size(tag_mem32), ATAG_MEM },
???????{ MEM_SIZE, PHYS_OFFSET },
???????{ 0, ATAG_NONE }
}

上述結(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鏈表
……
mdesc = setup_machine(machine_arch_type);// mdesc包含啟動(dòng)參數(shù)在內(nèi)存中的地址
if( mdesc->boot_params )
???????tags = phys_to_vert(mdesc->boot_params);// bootloader有傳遞啟動(dòng)參數(shù)到內(nèi)核
if( tags->hdr.tag != ATAG_CORE )
???????convert_to_tag_list(tags);//如果是舊的啟動(dòng)參數(shù)結(jié)構(gòu),將其轉(zhuǎn)成新的tag鏈表的形式
if( tags->hdr.tags != ATAG_CORE )
???????tags = (struct tag*)&init_tags;//轉(zhuǎn)換失敗,使用內(nèi)置的啟動(dòng)參數(shù)
if( tags->hdr.tag == ATAG_CORE )
{
???????if( meminfo.nr_banks != 0 )
??????????????squash_mem_tags(tags);//如果在meminfo中有配置內(nèi)存tag則跳過對(duì)內(nèi)存tag的處理
???????parse_tags(tags);
}


*:2.6.18內(nèi)核smdk2410meminfo沒有設(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)
{
???????for(; t->hdr.size; t=tag_next(t))
?????? {
?????????? if( !parse_tag(t))
??????????????printk();
?????? }
}

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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。