許世文 王慧
摘 要 Bootloader是嵌入式系統的重要組成部分,一般來說,Bootloader最重要的作用是用來加載操作系統,為調用操作系統內核準備好正確的環境。不過隨著半導體產業的發展,許多高性價比的MCU(微處理器)不斷推出市場,這些MCU有著豐富的外設資源,但是內部的存儲資源不足以運行嵌入式操作系統,只能運行微實時內核或無操作系統的應用,用來滿足低成本但相對智能化且需求易變的應用需求。由于應用功能的定制化以及系統維護等因素,也需要加入Bootloader來提高系統的靈活性。本文主要通過將著名的開源Bootloader(U-Boot)移植到ST(意法半導體)公司的一款高性價比微處理器STM32F103來闡述Bootloader的運行機理,需要說明的是,U-Boot雖然對多種處理器平臺、多種操作系統有著良好的支持,但其框架僅支持那些運行在內存(SRAM/DRAM/SDRAM)的操作系統且自身也需運行在內存中,而STM32F103的SRAM僅64K,不足以用來運行程序,故需對U-Boot的框架進行改造,使其不但自身運行在閃存(FLASH)中,并且可以直接引導閃存中的應用程序。這樣可使得類似于STM32F103這樣的“低端”嵌入式平臺也能共享U-Boot豐富的命令集和靈活的配置功能。
關鍵詞 Bootloader;U-Boot;STM32F103;嵌入式;FLASH
引言
嵌入式系統,是一種“完全嵌入受控器件內部,為特定應用而設計的專用計算機系統”。一般來說,計算機系統都具有相應的引導程序,它的作用是初始化硬件設備、完成必要的初始化過程,加載操作系統等。對于嵌入式系統來說,出于對成本、體積、性能、功耗等多方面因素考慮,除了使得Bootloader的設計不但嚴重依賴于硬件,甚至很多時候不再需要Bootloader。但一些特殊情況下,某些平臺的存儲資源不足以運行操作系統,僅能運行無操作系統的應用或者微型實時內核(如ucos-ii、FreeRTOS等),但又需要對系統的應用做靈活定制,這時也需要加入Bootloader讓系統變得更加靈活且方便維護。
本文主要內容是將著名的開源Bootloader -- U-Boot移植到一款“低端”嵌入式處理器平臺上,這里所謂的“低端”并非指檔次低,而是其存儲資源相對于U-Boot目前現支持的平臺來說要匱乏,需要對U-Boot進行相對較大的改動才足以支撐在其之上運行。事實上,這些“低端”的處理器在各個領域內的應用也是非常廣泛,這里要移植的處理器STM32F103就是當前非常流行的一款高性價比MCU,Cortex-M3核心,由ST公司出產。通過將U-Boot移植在這款MCU上,一方面能更好地理解Bootloader的運行機理,另一方面給出移植思路,方便讀者結合自己的項目靈活運用這款開源軟件,給項目的調試和應用帶來便利。
1 U-Boot移植STM32F103
1.1 設計思路
首先,先來看U-Boot的內存映射圖,U-Boot的設計者并不考慮那些僅運行在FLASH的嵌入式系統,如果按照圖中的存儲映射圖直接移植的話,即便進行裁剪,經過編譯后的映像也在60K左右,以STM32F103的內存(64K)肯定是無法滿足的,需要對U-Boot進行改造,將U-Boot駐留在FLASH中,就需要省去U-Boot將自身“搬移”到SRAM的步驟,使得內存中就剩下堆棧(.bss)和數據 (.data)。
其次,估算U-Boot除去自身映像之外對內存的需求,也就是圖中SDRAM除U-Boot映像之外的區域大小,由于STM32F103的中斷方式較為簡單,是靠中斷向量表直接跳轉,沒有單獨棧區,則IRQ&FIQ棧區也可省去。可先下載U-Boot源碼并找一種常用的平臺并編譯,得到內存映射文件后,計算U-Boot的內存需求。
最后,分析U-Boot的源碼框架和啟動流程,設計啟動流程框圖,搭建移植環境,并按照啟動流程圖設計程序,結合STM32F103的實際內存映射圖確認編譯和鏈接參數,編譯調試并最終得到正確的結果[1]。
1.2 設計過程
(1)估算內存需求
首先下載U-Boot源碼,為便于研究和移植,需要下載較老的版本u-boot.2010.06,較新的版本采用了動態鏈接地址的方法且編譯選項比較復雜,不利于我們對源碼的分析,方便起見,直接根據移植后的內存映射文件u-boot.map將存儲占用情況統計如下表,這里僅統計主要的數據和代碼段,還有一些段占用存儲較小直接略去。
從上表可以看出,前兩個段是代碼段和只讀段,可以駐留在FLASH中,后面的段是數據段,需要放在SRAM中,總大小不超過8K,加上堆和棧區,64K數據空間也已足夠。
(2)啟動分析
U-Boot對于很多平臺來說啟動流程大體相似,第一階段與硬件體系平臺相關,第二階段是通用功能,需要移植的重點主要在第一階段,以S3C2440單板為例,第一階段啟動大致工作為設置CPU模式和時鐘,判斷處理器啟動方式并重定位U-Boot映像,計算并設置堆棧指針,初始化bss段,與此同時建立CPU各個模式的中斷入口和獨立棧區,最終跳轉到通用功能的函數_start_armboot。
對于STM32F103來說,其硬件體系結構相對簡單。首先,其棧地址需要放在第一條指令中,被自動賦予sp(堆棧指針),故需要固定一個堆棧指針地址。其次,不需要考慮重定位,重定位其實就是判斷U-Boot自身是否運行在內存中,如果是運行在內存中,則不需要搬移直接跳轉到后面的代碼運行,否則將自身“搬運”至內存中,這是因為用仿真器來下載程序時,可能會將映像直接下載至內存中,而對于STM32F103映像始終是駐留在FLASH中,故程序流程圖如下所示:
(3)程序設計
按照U-Boot的目錄結構建立好相關文件,先根據CPU體系架構構造中斷向量表,中斷向量表可被所有Cortex-M3核心系列的MCU所共享,vectors_m.S文件的內容如下:
鏈接腳本.lds文件可根據其他平臺來設計編寫。然后通過編譯和調試就可以讓U-Boot在STM32F103上啟動了,需要移植的最基本的硬件驅動為定時器,串口,FLASH用來達到U-Boot最簡單的運行條件。
1.3 調試與應用
在調試的過程中,需要對存儲的分布有著清晰的理解和認識,編譯過后可以分析內存映射文件來確定數據代碼段是否放置在了正確的地址中,可避免盲目的調試。
移植完成后,應用程序的編寫也需要注意兩點,一是應用程序的運行地址,應用程序在編譯時,需要修改鏈接腳本保證FLASH空間的合理分配。二是應用程序需要將中斷向量表定位,當應用程序發生中斷時,默認會跳轉到FLASH的低地址的中斷向量表中運行程序,如果不重映射,那么會跳至U-Boot的中斷向量中(若低位地址存放U-Boot映像),需要在應用程序代碼中加入設置中斷向量表的語句,且MCU本身也支持[3]。
2 應用趨勢
當前,STM32系列的微處理器通過其超高的性價比以及良好的軟件服務,已經取得了非常好的市場占有額,其中的軟件服務就包括ST官方提供的STM32系列的Bootloader,其可以支持從多種接口引導,但是作為第三方軟件對一些系統的支持并非完全免費,網上還有很多開發者為STM32系列設計的Bootloader,但是其功能比起U-Boot還是稍遜一籌。
雖然在最新的U-Boot源碼下已經支持ST的一些單板平臺,但是其框架依舊是需要在DRAM/SDRAM中運行,并不能較好的支持在FLASH中運行,希望通過這篇文章給廣大嵌入式系統開發者一些思路,讓U-Boot支持更多的”低端”嵌入式平臺,給我們的系統調試和靈活設置帶來便利。
參考文獻
[1] 陳海軍,申衛昌,史穎.嵌入式系統引導程序詳探[J].計算機技術與發展,2006,16(1):123-125.
[2] 嚴菊明.基于ARM嵌入式系統的通用Bootloader的設計與實現[D].南京:東南大學,2005.
[3] 陳為軍,李正明,孫俊,等.基于U-BOOT的S3C44B0引導程序設計實現[J]微計算機信息,2007,23(2):113-115.