《朱老師物聯網大講堂》學習筆記
重定位引入和鏈結指令碼
位置無關編碼
位置有關編碼
我們在設計程式的時候會給程式指定乙個執行位址,
比如0xd0020010
這裡是通過鏈結器中指定來設定的,它的另乙個說法也叫鏈結位址,
鏈結位址可以通過上面的-ttext或者鏈結指令碼來指定。
程式的執行位址和我們的設定有關,即pic
位置無關**和指定的執行位址有關。
在現實中,大部分都是位置有關**
對於位置有關**而言,
最終執行的執行位址和編譯鏈結時侯給定的鏈結位址必須相同,
否則一定出錯。
arm-linux-ld -ttext 0x0 -o led.elf $^arm-linux-ld -ttext 0x0 -o led.elf $^
在這句命令中,我們用-ttext 0x0來指定鏈結位址是0x0,
這裡面該作何解釋呢?
這是因為s5pv210在內部做了對映,把sram對映到了我們這裡的0x0位址
在memory map中irom&iram裡面0x00000000和0xd0000000就是對映
我們目前涉及的**都還是位置無關**,所以其實還不存在這個問題
再來看看啟動過程
三星推薦的啟動方式中:bootloader必須小於96kb並大於16kb,假定bootloader為80kb,啟動過程是這樣子:先開機上電後bl0執行,bl0會載入外部啟動裝置中的bootloader的前16kb(bl1)到sram中去執行,bl1執行時會載入bl2(bootloader中80-16=64kb)到sram中(從sram的16kb處開始用)去執行;bl2執行時會初始化ddr並且將os搬運到ddr去執行os,啟動完成。ps:為什麼不直接載入完,還分2次,目前只能先解釋為,不知道bootloader是多大,所以分2次,也可能有一些其它的細節原因。
uboot實際使用的方式:uboot大小隨意,假定為200kb。啟動過程是這樣子:先開機上電後bl0執行,bl0會載入外部啟動裝置中的uboot的前16kb(bl1)到sram中去執行,bl1執行時會初始化ddr,然後將整個uboot搬運到ddr中,然後用一句長跳轉(從sram跳轉到ddr)指令從sram中直接跳轉到ddr中繼續執行uboot直到uboot完全啟動。uboot啟動後在uboot命令列中去啟動os。ps:這裡,是從ddr中uboot的16kb之後開始執行,
uboot的這種方式,更加靈活不用那麼麻煩,但是你從儲存空間大小上就可以看出來,它做了很多可以不用做的事情,所以有些廠商會針對自己的板子自己寫bootloader,大小很小,也很穩定。
在此引出衝定位的意義,鏈結位址和實際執行位址,沒辦法完全一致,又因為位置有關碼的存在,所以需要我們重定位,
還有一種解決上述載入的方法,是分散載入,分別指定bl1和uboot的鏈結位址,這種方式,也可以理解為一種手工重定位,重定位是以**的方式來實現的重定位
重定位引入和鏈結指令碼1
1 乙個事實 大部分指令是位置有關碼 位置無關碼 pic position independent code 彙編原始檔被編碼成二進位制可執行程式時編碼方式 生成的可執行程式 與位置 記憶體位址 無關。位置有關編碼 彙編原始檔被編碼成二進位制可執行程式後和記憶體位址是有關的。我們在設計乙個程式時,會...
重定位引入和鏈結指令碼
1 乙個事實 大部分指令是位置有關編碼 位置無關編碼 pic,position independent code 彙編原始檔被編碼成二進位制可執行程式時編碼方式與位置 記憶體位址 無關。位置有關編碼 彙編原始碼編碼成二進位制可執行程式後和記憶體位址是有關的。我們在設計乙個程式時,會給這個程式指定乙個...
重定位和鏈結指令碼
重定位實際就是在執行位址處執行一段位置無關碼pic,讓這段pic 也就是重定位 從執行位址處把整個程式映象拷貝乙份到鏈結位址處,完了之後使用一句長跳轉指令從執行位址處直接跳轉到鏈結位址處去執行同乙個函式,這樣就實現了重定位之後的無縫連線。鏈結位址 鏈結時指定的位址 指定方式為 makefile中用 ...