U-Boot 通過鏈接腳本 u-boot.lds 定義內存佈局:
ENTRY(_start)SECTIONS{ . = 0x00000000; .text : { cpu/arm920t/start.o(.text) *(.text) } .rodata : { *(.rodata) } .data : { *(.data) } .got : { *(.got) } __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .; __bss_start = .; .bss : { *(.bss) } _end = .;} ENTRY(_start) 指定入口符號。. = 0x00000000 並非真實運行地址,鏈接時會被 TEXT_BASE(如 0x33F80000)替換,所有符號地址均相對 TEXT_BASE 計算。u-boot.map 可見符號鏈接地址均為 0x33F8xxxx。_TEXT_BASE: .word TEXT_BASE 定義標號 _TEXT_BASE,其值為該指令的鏈接地址(即 TEXT_BASE),便於位置無關代碼引用基址。
.globl _armboot_start_armboot_start: .word _start _armboot_start 存儲 _start 的鏈接地址。u-boot.map 顯示其地址為 0x33F80044,二進制 u-boot.bin 偏移 0x44 處確為 0x33F80000(小端)。
.globl _bss_start_bss_start: .word __bss_start __bss_start 由鏈接腳本 __bss_start = . 定義,標記 BSS 段起始。_bss_start 處存儲該值(0x33F979D4),用於計算需搬運代碼大小(__bss_start - TEXT_BASE)。
ldr r0, =SMRDATALdr r1, _TEXT_BASEsub r0, r0, r1 @ r0 = SMRDATA 相對 TEXT_BASE 的偏移 核心邏輯:代碼尚未搬運至 SDRAM,運行於 Flash(加載地址 0x0),但符號地址基於 TEXT_BASE(鏈接/運行地址)。直接使用符號會導致地址錯誤。通過 SMRDATA - _TEXT_BASE 得到相對偏移,再加上當前 PC 基址,即可正確訪問 Flash 中的數據,實現位置無關代碼(PIC)。
relocate: adr r0, _start @ r0 = 當前代碼加載地址(PC 相對)ldr r1, _TEXT_BASE @ r1 = 運行地址 TEXT_BASEcmp r0, r1 @ 比較判斷是否已在正確位置 adr 取 PC 相對偏移,得到當前代碼實際加載地址(Flash 基址)。ldr 取絕對值 TEXT_BASE(SDRAM 目標地址)。_start ~ __bss_start 範圍複製到 TEXT_BASE,然後跳轉 start_armboot(C 入口)。此機制確保 U-Boot 能從 Flash 啟動、自動重定位到 SDRAM 高速運行,是嵌入式 Bootloader 的經典設計。
Linux Shell 判斷結構全解析:test、[ ]、[[ ]]、(( )) 與 let
Linux 進程監控自動重啟 Shell 腳本編寫實戰(以 Tomcat 為例)
Linux lftp 連線 FTP 伺服器上傳下載實戰:mirror 目錄同步、mget/mput、書籤、檔案檢視
Debian/Ubuntu 網路設定完整指南:靜態 IP、DHCP 與 DNS 設定
Linux 開機自動執行自訂腳本完整教學(SysV init / chkconfig)
Linux 開發環境必修課:Vim 編輯器從入門到精通完整指南