uboot移植過程中的執行位址和裝載位址的區別

2021-06-26 06:24:40 字數 3015 閱讀 9227

uboot移植涉及到底層硬體的設定,因此需要掌握uart、系統時鐘頻率、nor flash、nand flash、sdram、網絡卡、儲存控制器等硬體的功能及配置,這些都可以參照相應開發板的晶元手冊來完成,沒有什麼大的問題。在移植過程中,一直困擾我的是pic(**無關性)問題,即執行位址和載入位址的區別,看過網上很多關於這兩者的介紹,感覺懂一點,卻一直不知所然。在參考大量的文獻下,算是得了一點心得。

首先來了解下執行位址及載入位址的區別

執行位址和載入位址的值有時相等,有時卻不相等,所以這給初學者帶來很大的困擾。為了弄清楚這個問題,還得從nor flash,nand flash,s3c2440內部4kb ram的對映說起。

左邊表示從nor flash啟動時的對映,右邊表示從nand flash啟動時的對映。

這裡只討論從nor flash啟動的情況,從圖中可以看出nor flash對映到了0x00000000的起始位置,假如uboot的**存放在nor flash上,即裝載位址為0x00000000。再來看看uboot的鏈結位址,**在board/smdk2410/u-boot.lds裡。

連線指令碼檔案lds中沒有設定lma,只是設定了vma。vma的設定是通過頂層目錄下的config.mk檔案中的ldflags實現的

在board/smdk2410/config.mk定義了text_base = 0x33f80000(sdram),即程式的執行位址

檢視u-boot.map檔案,**的連線位址是從0x33f80000開始的。

167 .text         0x33f80000        0x232c8

168        cpu/arm920t/start.o(.text)

169        .text                0x33f80000                0x4a0 cpu/arm920t/start.o

170                                0x33f80048                _bss_start

171                                0x33f8004c                _bss_end

172                                0x33f80044

_armboot_start

173                                0x33f80000

_start

174        board/samsung/fs2410/lowlevel_init.o(.text)

175        .text                0x33f804a0         0x64 board/samsung/fs2410/lowlevel_init.o

176                                0x33f804a4                lowlevel_init

177        board/samsung/fs2410/nand_read.o(.text)

178        .text                0x33f80504        0xe8 board/samsung/fs2410/nand_read.o

179                                0x33f80504                wait_idle

180                                0x33f80518                nand_read_ll

此時裝載位址和執行位址明顯不一樣,為什麼程式還能執行呢?這裡就涉及到pic----**無關設計方面的知識了。在組合語言中,像bl、b、adr(adr屬於偽指令,一般被編譯器解釋成sub指令)指令屬於位置無關指令,不管程式裝載在哪個位置上,bl、b、adr指令都能正確的執行,其原因是bl、b、adr指令的位址域是基於pc的相對偏移定址,相當於[pc+offset]。當arm啟動時,arm自動取0x00000000位置上的指令,此時pc=0x00000000。

基於pc偏移量的指令都能正確的執行。所以uboot第一階段指令都能執行的原因在於此。

但我們回顧一下u-boot的啟動過程中的第一階段有將u-boot**複製到sdram中,並跳到sdram中去執行,因為sdram對映到了bank6,其位址為0x30000000,此時uboot**的位址範圍從 text_base----text_base+size(u-boot),程式是如何跳轉的呢?跳轉到sdram為何還能執行呢?這裡就需要看下cpu/arm920t/start.s中的relocate標號。

relocate: 把norflash中的**複製到_text_base處,在board/smdk2410/config.mk定義了text_base = 0x33f80000,這個位址屬於bank6的範圍。也就是把**複製到從_text_base位址開始的sdram中,當然在複製之前是要初始化sdram的,要不然sdram沒法使用。至此,**已複製到sdram中,那麼就要跳到sdram中去執行,跳轉之前要做stack設定,清bss,這些就不說了。下面來說如何跳轉的,請看下面這條指令。

ldrpc, _start_armboot

ldr偽指令中目的暫存器如果是pc,則ldr是與位置相關的指令,

u-boot.map檔案可以看出,

_start_armboot=

0x33f80044, 即pc=0x33f80004。這樣uboot就跳到sdram上去執行了,且這條指令剛好處在其執行位址處,所以程式就能正確的執行。

U Boot移植過程中的執行位址和裝載位址的區別

連線指令碼檔案lds中沒有設定lma,只是設定了vma。vma的設定是通過頂層目錄下的config.mk檔案中的ldflags實現的 在board smdk2410 config.mk定義了text base 0x33f80000 sdram 即程式的執行位址 檢視u boot.map檔案,的連線位...

uboot移植過程中的執行位址和裝載位址的區別

連線指令碼檔案lds中沒有設定lma,只是設定了vma。vma的設定是通過頂層目錄下的config.mk檔案中的ldflags實現的 在board smdk2410 config.mk定義了text base 0x33f80000 sdram 即程式的執行位址 檢視u boot.map檔案,的連線位...

Spark執行過程中的錯誤

配置完歷史伺服器之後測試saprkpi案例報以上錯誤。原因在於 spark env.sh和spark defaults.conf中配置logdierctory的路徑埠為8020 預設埠 這樣不對,因為spark產生的日誌檔案儲存到hdfs中,所以spark訪問hdfs的uri應該與hadoop的co...