1. 程式人生 > >IMX6Q的uboot.imx檔案解析

IMX6Q的uboot.imx檔案解析

文章目錄


經過幾天的研究,徹底弄清楚了IMX6的ROM BOOT 流程,以及如何啟動uboot;2016-03 版本的uboot原始碼編譯後生成的uboot.bin與uboot.imx是什麼關係,怎麼生成uboot.imx等等。
下面就把寫的筆記搬到這裡來,方便以後查閱。

uboot.imx與uboot.bin的關係

u-boot.imx與u-boot.bin檔案的主要關係是:u-boot.imx是在u-boot.bin的前面附加上一個image header,主要包含IVT header、 Boot data、DCD header;整個header的大小限制為3Kbyte。
為啥限制大小為3K,是因為在儲存器的0 地址預留一部分空間儲存分割槽資訊,以下表格為不同儲存器型別預留的空間大小。
在這裡插入圖片描述

根據預留空間大小,將u-boot.imx檔案燒寫到eMMC時,需要偏移1K位元組,下圖為u-boot.imx在eMMC空間的分佈。
在這裡插入圖片描述

uboot.imx檔案解析

瞭解了u-boot.imx在eMMC空間的分佈之後,下面就詳細介紹IVT header、Boot Data、DCD header三個部分的細節。以下圖所示為u-boot.imx的前一部分,下面詳細解釋其含義:
在這裡插入圖片描述

在這裡插入圖片描述

IMX6 ROM BOOT 流程中IVT、Boot data、DCD等相關資料操作

當我們選擇從eMMC啟動時,BOOT ROM會拷貝eMMC中的前4K bytes資料到片內RAM(OCRAM)。這初始的4K資料中必須包含IVT(Image vector table)、DCD(Device configuration data)和Boot Data structures,但eMMC啟動時,IVT的偏移為1K,所以剩餘的3K資料中必須包含IVT、DCD和Boot Data structures。(其實不到1K)

另外DCD最大長度限制由巨集 MAX_HW_CFG_SIZE_V2決定,巨集在\u-boot-2016.03-r0\tools\imximage.h檔案中定義,在手冊文件8.6.2 Device Configuration Data (DCD)節說明DCD最大長度為1768byte

為何拷貝的是eMMC的欠欠4K資料:因為在\u-boot-2016.03-r0\tools\imximage.h檔案中定義
#define FLASH_LOADSIZE_STANDARD 0x1000;此巨集定義說明BOOT ROM將eMMC起始的4K內容拷貝到片內RAM

接著BOOT ROM檢查OCRAM 4K資料中包含的IVT頭標誌0xD1,然後執行DCD檢查。這些檢查無誤通過後,從boot data structure 中解析出下一步拷貝的目的地址和長度(記為length),然後從eMMC地址0,拷貝長度length的資料到上面解析出的目的地址處。

這裡有一個如何在OCRAM中定位boot data structure地址的問題。編譯生成的u-boot.imx,它的boot data內容即為boot data structure的地址,而該地址是一個絕對地址,實際為DDR地址,而OCRAM中此時的地址還是原始資料中的該地址。由於此時DDR還未準備好,還未執行u-boot.imx到DDR的拷貝,BOOT ROM不能使用boot data中的絕對(DDR地址)地址來定位boot data structure。而只能使用偏移地址在OCRAM中定位boot data structure。那麼偏移地址怎麼得到呢?

注意IVT中還有一個self表項,它指向它自身,即IVT的首地址。此例u-boot.imx中的self的值為0x177FF400,boot_data的值為0x177FF420,那麼boot data structure的地址偏移為boot data structure offset = boot_data - self(IVT首地址) = 0x20,載入到OCRAM中後,boot data structure的有效地址為:OCRAM IVT 載入首地址 +boot data structure offset,同理也可以計算出DCD資料在OCRAM中的偏移為0x2C。

其實不用這麼麻煩,根據u-boot.imx在eMMC儲存器中的空間分佈,IVT header佔用固定的0x20 位元組,緊接著就是boot data structure,佔用0x0C位元組;然後是DCD header;所以boot data的偏移為0x20 位元組,DCD header 的便宜為0x2C位元組;因此當ROM BOOT將eMMC的前4K空間拷貝到OCRAM中時 ,偏移並不會改變。

ROM BOOT在經過以上步驟以後,根據這些地址定位找到DCD的儲存位置,使用DCD中的配置引數,來初始化DDR,配置時鐘,以及其他啟動時必要的硬體設定; BOOT ROM會在必要的檢查和上述的初始化之後,將boot data structure資料指示的地址與長度將uboot.imx資料拷貝到SDRAM然後跳轉到IVT指示的entry執行uboot
uboot.imx在eMMC中的分佈與拷貝到SDRAM中的分佈如下圖所示:

在這裡插入圖片描述

uboot.imx檔案生成

u-boot-2015.07及以後的版本中,更改了u-boot.imx的產生方式,不再使用flash_header.S,而是使用mkimage工具直接生成。
mkimage包含的目標檔案型別-T引數中新增了imximage選項;mkimage會呼叫格式型別imximage的直譯器來生成針對i.mx(5系6系)系列晶片的 IVT、boot Data、DCD的格式頭。
具體的程式碼實現在tools/imximage.c中。我們以board/freescale/mx6qsabreauto為例,生成u-boot.imx時執行:
./tools/mkimage -n board/freescale/mx6qsabreauto/imximage.cfg.cfgtmp -T imximage -e 0x17800000 -d u-boot.bin u-boot.imx
其中-n指明輸入檔案為imximage.cfg.cfgtmp,-T指明直譯器為imximage,-e為映象程式入口點。
mkimage呼叫選項-T的imximage 直譯器解析輸入檔案:imximage.cfg.cfgtmp,而檔案imximage.cfg.cfgtmp為imximage.cfg編譯時處理(使用gcc -E選項)後產生的臨時檔案。
更多細節需要參考imximage.c程式碼實現。

猜想

由於IMX6 的ROM BOOT會將uboot.imx拷貝到SDRAM的0x177FF000,加上4K的image header偏移,uboot.bin正好對應到連結地址:0x17800000,因為uboot在執行程式碼時已經在連結地址,所以應該不會進行程式碼重定位操作