Linux核心引數傳遞Tag

2021-06-19 01:17:28 字數 2777 閱讀 1960

在2.4(具體哪個版本記不清了)以後的linux核心中引入了一種新的向核心傳遞引數的方法tag標記。核心引數通過乙個靜態的tag鍊錶在啟動的時候傳遞到核心。每個tag的結構為

tag_header

tag_***

其中tag_header為tag頭,表明tag_***的型別和大小,之所以要標識tag_***的型別是因為不同的tag需要不同的處理函式(下文講tagtable的時候會分析到)。tag_header的結構為

struct tag_header

size表示tag的結構大小,tag為表示tag型別的常量。這個靜態的鍊錶必須以tag_header.tag = atag_core開始,並以tag_header.tag = atag_none結束。由於不同的tag所使用的格式可能不盡相同,所以核心又定義了乙個結構tagtable來把tag和相應的操作函式關聯起來

struct tagtable

其中tag為標識入atag_none,atag_core等。parse為處理函式。linux核心將tagtable也組成了乙個靜態的鍊錶放入.taglist.init節中,這是通過__tagtable巨集來實現的

#

define __tag __attribute_used__ __attribute__(

(__section__ (「.taglist.init」)))

#define __tagble(tag,fn)

static

struct tagtable __tagtable_#

#fn __tag =

以處理命令列引數為例:

static

int __init parse_tag_cmdline(

const

struct tag* tag)

__tagtable(atag_cmdline, parse_tag_cmdline)

可以看到parse_tag_cmdline將命令列引數拷貝到default_command_line裡,__tagtable將atag_cmdline和parse_tag_cmdline掛鉤。

以上已經分析了核心和tag相關的兩個重要結構。現在分析具體的實現。核心中定義了一些預設的tags

static

struct init_tags

init_tags __initdata =,,

,,}

上述結構中乙個tag_header和tag_***形成了tag的完整描述,tag_size返回tag_head和tag_***的總大小,在tag_size中我們要注意的是u32*指標加1位址值實際上位址加了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實際上計算的是(tag_head+tag_***)/4。經過進一步的分析還發現每個tag在記憶體中的大小並不是相同的,這一點可以從tag_next看出,tag_next只是將指標移到了下乙個tag的tag_header處,這種記憶體布局更加緊湊。對tag的處理**在arch/arm/setup.c setup_arch裡面。以下是一部分的關鍵**

struct tag *tags =

(struct tag*

)&init_tags;

//tags指向預設的tag鍊錶

……mdesc = setup_machine(machine_arch_type)

;// mdesc包含啟動引數在記憶體中的位址

if( mdesc-

>boot_params )

tags = phys_to_vert(mdesc-

>boot_params)

;// bootloader有傳遞啟動引數到核心

if( tags-

>hdr.tag !

= atag_core )

convert_to_tag_list(tags)

;//如果是舊的啟動引數結構,將其轉成新的tag鍊錶的形式

if( tags-

>hdr.tags !

= atag_core )

tags =

(struct tag*

)&init_tags;

//轉換失敗,使用內建的啟動引數

if( tags-

>hdr.tag =

= atag_core )

*注:2.6.18核心smdk2410

的meminfo

沒有設定

nr_banks

,所以必須在核心的啟動引數裡面傳遞

mem=」memory size」@」memory base address」

,否則系統識別記憶體錯誤,這點從系統的啟動資訊就可以看出來,而且在載入

initrd

的時候也會遇到記憶體溢位的錯誤

static

void __init parse_tags(

const

struct tag* t)

}

parse_tags遍歷tag鍊錶呼叫parse_tag對tag進行處理。parse_tags在tabtable中尋找tag的處理函式(通過tag_header結構中的tag)。

u boot向Linux核心傳遞引數tag原理分析

u boot最主要的功能是引導os,目前對linux支援的相對比較好,引導 的意義不僅僅是拷貝核心,執行核心,還要給核心kernel傳遞板子的相關引數,打個比方,u boot相當於是一名專業功底深厚的 接待員 他會先初始化好一些外圍裝置,比如說串列埠,sdram nand flash mmc等,初始...

Linux核心模組傳遞引數

如果需要向核心模組中傳遞引數,可以使用函式 module param 引數名,引數型別,讀寫許可權 1 引數名稱 不必解釋 2 引數型別 byte,short,short,int,uint,long,ulong,charp,bool,invbool 3 讀寫許可權 一般為s irugo 例子 傳遞乙...

Linux 核心 給模組傳遞引數

對於如何向模組傳遞引數,linux kernel 提供了乙個簡單的框架。其允許驅動程式宣告引數,並且使用者在系統 啟動或模組裝載時為引數指定相應值,在驅動程式裡,引數的用法如同全域性變數。使用下面的巨集時需要包含標頭檔案 moduleparam.h 通過巨集module param 定義乙個模組引數...