通過前面的調試了解到s5pv210這個芯片的啟動流程是需要將u-boot分為兩部分的分別為SPL和u-boot。這里我使用網上的方式不直接使用u-boot的SPL連接腳本單獨生成SPL的image而是用前面介紹的方法 [https://www.cnblogs.com/w-smile/p/13124631.html](u-boot 移植 --->3、S5PV210啟動序列)將u-boot的前16k直接截取出來作為SPL。
IROM中
這一部分可以參考其他博文,或者三星的文檔。
在IRAM中
通過啟動連接腳本archarmcpuu-boot.lds 我們找到了整個代碼的入口_start。全局尋找找到文件archarmlibvectors.S符合本次架構所以整個代碼入口就在這里內容如下:
_start:
#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
.word CONFIG_SYS_DV_NOR_BOOT_CFG
#endif
b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
所以可以看出來這里也是符合ARM架構要求,在這里定義了中斷向量表,然后第一句指令是一個跳轉指令,將執行流跳轉到reset符號了,經過查找這個符號定義在archarmcpuarmv7start.S 這是架構通用的部分所以可以參考u-boot源碼這里僅羅列這段程序操作的內容:
1. 檢查是否使能了大物理頁面擴展,如果使能了則進行必要的配置。(CP15)
2. 禁止IRQ和FIQ,配置處理器模式為SVC。(CPSR)
3. 設置_start 符號地址為異常向量表基址,并禁止cache,TLB,BP,MMU(CP15)
4. 調用lowlevel_init(如果定義了CONFIG_SKIP_LOWLEVEL_INIT_ONLY則不執行),這一部分就是芯片移植人員需要早期初始化的內容可以放在這個標號下實現,我這里就是配置時鐘,配置芯片DRAM接口,配置UART0。
5. 設置堆棧為IRAM空間,并拷貝SD卡中特定地址的完整u-boot鏡像到DRAM指定地址,SD的驅動實在芯片的IROM中完成的。(這一部分是本來的u-boot內容沒有的因為我們未使用u-boot的SPL方式單獨構建SPL程序所以修改了這部分內容)。
DRAM中
完成上面的操作后進行絕對跳轉就能到DRAM地址空間繼續運行代碼了,因為代碼本身就是連接在這個地址的。跳轉后運行_main 符號處的指令他實現在rcharmlibcrt0.S 中操作序列大致如下:
1. 重新修改棧基址到DRAM地址空間中
2. 調整棧指針 (實際則是在棧中分配內存)這里是為malloc和struct global_data 的GD變量預留內存
3. 初始化 GD變量的部分成員,這是整個u-boot的一個重要的全局數據用來記錄各種數據狀態等。
執行了以上的處理步驟后將又可以使用C代碼調用了。然后調用board_init_f 這是在commonboard_f.c 中實現的屬于u-boot的內容的代碼,主要就是圍繞GD變量進行操作詳細的操作這里不深入分析,就是進行一些配置初始化相關的主要就是調用initcall_run_list 這個函數依次執行一個初始化list進行初始化,這個初始化函數數組init_sequence_f也是在commonboard_f.c 中定義并根據u-boot的使用kbuild配置產生的配置文件編譯生成。其中大部分初始化函數都是平臺無關的少量與平臺相關需要注意對應修改下,除此之外需要注意的是在這里執行board_init_f 相關調用時有打開cache。這里執行完成后GD變量的成員也越來越完善,再次根據GD中記錄的信息修改SP棧指針。然后還需要再次移動并重定位代碼,這一次移動是為了為了將u-boot放到DRAM高地址為拷貝Linux內核image準備空間,拷貝完成后無效指令和數據cache(因為原來地址空間的緩存已經無效了)。這里還使用了一個技巧使拷貝完成后直接返回到新地址的下一條指令執行。使用的方式就是在LR寄存器上做文章,具體參考代碼實現。然后在次修改異常向量表地址到新的地址空間。注意的是這里代碼重定向還是比較復雜一點的不是簡單的拷貝,因為前面的GD變量也是需要維護的,主要就是然后對新地址的數據段的拷貝。然后就是調用commonboard_r.c 文件中的board_init_r 函數,這個函數的實現和board_init_f 如出一轍他們末尾的字母就是標記他們調用的配置是在重定向前(f)和之后(r)執行的初始化。最后執行的就是 run_main_loop這里就是u-boot程序的主循環,在這里進行u-boot命令等相關功能的操作。
總結
u-boot的整個執行過程的粗流程其實是不復雜的,調試過程最復雜的感覺就是DRAM的配置那些部分。整個移植實際上出去kbuild配置工具外就是,一部分關于底層的初始化配置相關內容,其余就是u-boot的大致執行流程。流程我在做一下梳理總結如下:
_start(archarmlibvectors.S)向量表,然后跳轉(reset)--->archarmcpuarmv7start.SARM 架構相關的操作,調用(lowlevel_init)---> 平臺相關的底層或前提初始化部分的必要配置,調用(_main)--->archarmlibcrt0.S 進行u-boot相關功能的變量,棧等部分的維護初始化等,調用(board_init_f)--->commonboard_f.c 根據配置調用以系列的初始化調用,返回crt0.S,重定位u-boot代碼在DRAM中的位置,調用(board_init_f)--->commonboard_r.c 繼續進行必要的初始化--->u-boot loop(如果引導Linux則u-boot就執行完了)。如果像知道更詳細的內容可以參考這個博主的博客:https://to-run-away.blog.csdn.net/article/details/81711413?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.control
上一篇:ARM匯編指令-STMFD/LDMFD
下一篇:u-boot 移植 --->5、友善之臂Tiny210底板王網卡驅動移植
推薦閱讀最新更新時間:2025-05-04 10:17





設計資源 培訓 開發板 精華推薦
- 4w智能小車stm32
- 用于汽車應用的 LTC3643EUDD 12V 備份系統的典型應用電路
- C596309_STM32F411CEU6方案驗證板
- CHEEKY PI_V1 壞蛋派 STM32G431CBU6
- LT3791EFE-1 98% 效率 60W (12V/5A) LED 驅動器的典型應用電路
- wifi遠程開機
- DC2093A-C,用于 LT4275C PD 控制器的演示板,符合 IEEE 802.3af 規范
- 禁用看門狗的 LTC2938IMS 四電源監視器的典型應用電路
- 使用 Analog Devices 的 LTC4053 的參考設計
- LTC3401,全陶瓷電容器 2 節轉換器在 500mA 時提供 3.3V