uboot (番外篇)uboot之fdt介紹

2021-08-28 03:17:17 字數 4285 閱讀 2158

以下例子都以project x專案tiny210(s5pv210平台,armv7架構)為例

[uboot] uboot流程系列: 

[project x] tiny210(s5pv210)上電啟動流程(bl0-bl2)

[project x] tiny210(s5pv210)從儲存裝置載入**到ddr

[uboot] (第一章)uboot流程——概述

[uboot] (第二章)uboot流程——uboot-spl編譯流程

[uboot] (第三章)uboot流程——uboot-spl**流程

[uboot] (第四章)uboot流程——uboot編譯流程

[uboot] (第五章)uboot流程——uboot啟動流程

[uboot] (番外篇)global_data介紹

[uboot] (番外篇)uboot relocation介紹

建議先看《[[uboot] (番外篇)uboot relocation介紹》和《[uboot] (第四章)uboot流程——uboot編譯流程》

因為在學習uboot的driver module,發現有必要先把uboot的fdt整明白點。所以這裡就先學習一下fdt咯。

fdt,flatted device tree,扁平裝置樹。熟悉linux的人對這個概念應該不陌生。 

簡單理解為將部分裝置資訊結構存放到device tree檔案中。 

uboot最終將其device tree編譯成dtb檔案,使用過程中通過解析該dtb來獲取板級裝置資訊。 

uboot的dtb和kernel中的dtb是一致的。這部分建議直接參考wowo的dtb的文章 

device tree(一):背景介紹

device tree(二):基本概念

device tree(三):**分析

關於uboot的fdt,可以參考doc/readme.fdt-control。

結構體如下

dtb header

alignment gap

memory reserve map

alignment gap

device-tree structure

alignment gap

device-tree string

dtb header結構如下:

結構體如下

magic

totalsize

off_dt_struct

off_dt_strings

off_mem_rsvmap

version

……其中,magic是乙個固定的值,0xd00dfeed(大端)或者0xedfe0dd0(小端)。 

以s5pv210-tiny210.dtb為例: 

執行」hexdump -c s5pv210-tiny210.dtb | more」命令

@:dts$ hexdump -c s5pv210-tiny210.dtb | more

00000000 d0 0d fe ed 00 00 5a cc 00 00 00 38 00 00 58 14 |......z....8..x.|

00000010 00 00 00 28 00 00 00 11 00 00 00 10 00 00 00 00 |...(............|

可以看到dtb的前面4個位元組就是0xd00dfeed,也就是magic。 

綜上,我們只要提取待驗證dtb的位址上的資料的前四個位元組,與0xd00dfeed(大端)或者0xedfe0dd0(小端)進行比較,如果匹配的話,就說明對應待驗證dtb就是乙個合法的dtb。

dtb可以以兩種形式編譯到uboot的映象中。

dtb整合到uboot的bin檔案內部

另外,也可以通過fdtcontroladdr環境變數來指定dtb的位址

可以通過直接把dtb載入到記憶體的某個位置,並在環境變數中設定fdtcontroladdr為這個位址,達到動態指定dtb的目的。 

在除錯中使用。

以tiny210為例,具體可以參考project x專案中uboot的git記錄:8a371676710cc0572a0a863255e25c35c82bb928 

(1)在makefile中新增對應的目標dtb 

arch/arm/dts/makefile

dtb-$(config_target_tiny210) += \

s5pv210-tiny210.dtb

(2)建立對應的dts檔案 

arch/arm/dts/s5pv210-tiny210.dts,注意檔名要和makefile中的dtb名一致

/dts-v1/;

/;

(3)開啟對應的巨集 

configs/tiny210_defconfig

config_of_control=y

config_of_separate=y ##其實這裡不用配,arm預設就是指定這種方式

(4)因為最終的編譯出來的dtb可能會多個,這裡需要為tiny210指定乙個dtb 

configs/tiny210_defconfig

config_default_device_tree="s5pv210-tiny210"
編譯,解決一些編譯錯誤,就可以發現最終生成了u-boot.dtb檔案。 

通過如下「hexdump -c u-boot.dtb | more」命令可以檢視我們的dtb檔案,得到部分內容如下:

hlos@node4:u-boot$ hexdump -c u-boot.dtb | more

00000000 d0 0d fe ed 00 00 01 a4 00 00 00 38 00 00 01 58 |...........8...x|

00000010 00 00 00 28 00 00 00 11 00 00 00 10 00 00 00 00 |...(............|

00000020 00 00 00 4c 00 00 01 20 00 00 00 00 00 00 00 00 |...l... ........|

00000030 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 |................|

在uboot初始化過程中,需要對dtb做兩個操作:

這部分過程是在init_board_f中實現,參考《[uboot] (第五章)uboot流程——uboot啟動流程》。

對應**common/board_f.c

static init_fnc_t init_sequence_f =
後面進行具體函式的分析。

對應**如下: 

lib/fdtdec.c

int fdtdec_setup(void)

/* fdtdec_prepare_fdt實現如下 */

int fdtdec_prepare_fdt(void)

return 0;

}

驗證dtb的部分可以參考《[kernel 啟動流程] (第四章)第一階段之——dtb的驗證》。

relocate的內容請參考《[uboot] (番外篇)uboot relocation介紹》。 

common/board_f.c中

static int reserve_fdt(void)

#endif

return 0;

}

relocate的內容請參考《[uboot] (番外篇)uboot relocation介紹》。 

common/board_f.c中

static int reloc_fdt(void)

#endif

return 0;

}

gd->fdt_blob已經設定成了dtb的位址了。 

注意,fdt提供的介面都是以gd->fdt_blob(dtb的位址)為引數的。

以下只簡單說明幾個介面的功能,沒有深究到實現原理。先說明幾個,後續繼續補充。 

另外,用節點在dtb中的偏移位址來表示乙個節點。也就是節點變數node中,存放的是節點的偏移位址

lib/fdtdec_common.c中

uboot移植之uboot和kernel的引數傳遞

從uboot啟動核心的形式thekernel 0,machid,bd bi boot params 可以看出uboot給核心傳遞了3個引數,第1個是0,第2個是機器碼,第3個是引數列表在sdram的起始位置 剛好滿足一下呼叫核心的條件 r0 0。r1 機器型別id r2 啟動引數標記列表在ram 中...

uboot移植之uboot命令體系解析

1 回歸到main loop uboot啟動第二階段的最後,進入死迴圈main loop 函式,命令列中沒輸出一次命令,就會執行一次main loop函式,完成一次命令的獲取 解析和執行。2 uboot命令體系的實現原理 uboot中裡面維護了很多命令,每個命令對應乙個結構體變數,當我們在命令列輸入...

AWS學習番外篇之SDK For Java

每個aws服務都有乙個服務介面,提供了與服務api 中對應的方法。如 amazon dynamodb的服務介面名是amazondynamodb。每個服務介面都有對應的客戶端生成器,用於構建服務介面。1.獲取客戶端生成器的例項,使用靜態工廠方法standard。amazondynamodbclient...