資料來源: Bootloader與Kernel間參數傳遞機制
Tag list 被用來在 bootloader 和 linux kernel 之間傳遞參數,這裡分析一下相關的數據結構,主要包括兩個部分: Tag list 和 Tag parser list 。
先來看 Tag list :
這個 list 是在 bootloader 中填充的,其數據結構定義在 bootloader 和 linux kernel 中均有定義,是一致的。我們來看 linux kernel 中的定義:
top/arch/arm/include/asm/setup.h |
其中 tag 的取值如下,暫且稱之為 tag type :
# define ATAG_CORE 0x54410001 |
其數據結構用圖形表示就是:
其實就是一個鏈表,通過 Tag size 以及當前 tag 的位置來定位下一個 tag 的位置。而且第一個 tag 的類型必然是 ATAG_CORE 。
參數就是按照這個結構進行傳遞的,那麼 kernel 是如何進行解析的呢?
我們來看 tag parser list:
同樣是在 top/arch/arm/include/asm/setup.h ,有如下定義:
top/arch/arm/include/asm/setup.h
struct tagtable { |
從上面知道, tag parser list 存在於 .taglist.init 段,他們的定義將通過宏 __tagtable(tag, fn) 的形式給出,比如在 top/arch/arm/kernel/setup.c 中:
top/arch/arm/kernel/setup.c
__tagtable( ATAG_CORE, parse_tag_core) ; |
通過這樣的定義,每個 tag table 的表項就自 動連接在了一起,而且存在於同一個段中。如圖所示:
可以看到,所有支持的 tag parser 都列在這 裡了。
在 kernel 中,將針對 tag list 中的每一項在這個 tag parser list 中進行查找,如果有 對應的處理項,則調用解析函數,於是就完成了參數的傳遞以及解析!
注意:
在 top/arch/arm/kernel/head-common.s 中會對從 bootloader 傳遞過來的 tag list 進行合法性判斷:
以標號 __vet_atags 開始的一段處理就要是 判斷 tag list 的第一項是否是 ATAG_CORE ,同時判斷長度是否越界!
No comments:
Post a Comment