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...