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