天天看點

關于xloader和uboot的幾個初級問題

在看代碼的過程中遇到的幾個問題,發郵件問了xf,得到了滿意的回答,對xf表示感謝。

這裡将問題及答案記錄下來,作為參考,藍色的字型為xf給我的回答。

 一、為什麼需要xloader,xloader所做的工作為什麼不直接就讓uboot做,而要單獨的分出來呢?

我看了xloader的代碼,非常短小,所做的工作也很簡單, 我說說我對代碼的了解,不知道正不正确:

在最初始的時候xloader首先對系統進行了初始化(sys_ init和ddr_init),然後就進入Xloader_ Entry函數,從預定的flash位址(UBOOT_ BASE_ADDRESS 0xF8010000)讀取uboot image的header, 然後比較讀取的header中的magic number與預定的magic number(IH_MAGIC 0x27051956)是否相同, 如果相同則說明在flash中存在uboot的image。 在确定了uboot的存在之後,根據uboot image header中指定的記憶體位址loadaddress以及資料大 小data_size将uboot載入記憶體, 然後在執行了Program_Interconnection_ Matrix之後, 就跳轉到loadaddress開始執行uboot的代碼。

如果xloader僅僅完成了上述的功能的話, 那為什麼不能直接将xloader的功能就內建到uboot中呢 。

xloader主要功能是:初始化系統時鐘;初始化外部記憶體,對我們目前項目就是DDR;引導UBOOT

xloader的運作環境為内部記憶體sram;這部分是在chip内部,材料比較貴,都是很小一部分空間,不能夠運作大的程式。

chip總是留這樣一部分sram運作bootrom代碼和xloader代碼,對這兩部分代碼的大小進行了限制。是以xloader都很小

功能簡單,獨立于uboot,uboot功能較多,相當于小系統,代碼較大,隻能在外部記憶體運作。

啟動順序:bootrom(内部ram)-》xloader(内部ram)-》uboot(外部ram)-》kernel(外部ram)

二、從xloader跳轉到uboot之後程式是怎麼走的?

注意到在xloader中有以下幾句代碼:

loadaddress = ntohl(hdr->ih_load);

data_size = ntohl(hdr->ih_size);

memcpy(loadaddress, (UBOOT_BASE_ADDRESS + 64), data_size);

由此可見,xloader将uboot image中的data_ size個位元組拷貝到了loadaddress的記憶體區域内, 并且拷貝的位元組區域相對于UBOOT_BASE_ ADDRESS(即uboot的燒寫位址0xF8010000) 的偏移為64個位元組。

分析程式可知,在UBOOT_BASE_ ADDRESS處是uboot image header,而image header結構的定義為

typedef struct image_header {

    uint32_t    ih_magic;

    uint32_t    ih_hcrc;

    uint32_t    ih_time;

    uint32_t    ih_size;

    ...

}  image_header_t;

也就是說, header偏移64個位元組的地方正是header中的ih_ time, 也就是loadaddress記憶體區域開頭處的内容為ih_ time。

這樣的話,一旦在xloader執行了Jump_To_ UBoot(loadaddress)之後, 程式将跳轉到loadaddress出執行, 而此時loadaddress處的内容卻為ih_time, 到這個地方,程式是怎麼執行了呢?

這部分沒明白啥意思,xloader裝載uboot後,直接跳轉到uboot執行就ok了

...

第二個問題我明白你的意思了,

uint32_t不是32個位元組啊,

uboot前邊的header總共64個位元組

哦,我明白了,它也真是,直接寫sizeof(image_ head_t)不就行了嗎,非得寫64。 不過也是我自己粗心大意了。

三、說了一大堆, 其實我就是想在源代碼級别上了解整個系統從一開始到linux内 核成功引導的全過程。

對于第三個問題,由于不是一句兩句就能夠說清楚的,是以準備過幾天親自去找xf問清楚,但是在這之前,我需要先盡量看代碼。

繼續閱讀