<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 基于ARM的嵌入式系統(tǒng)Bootloader啟動流程分析

          基于ARM的嵌入式系統(tǒng)Bootloader啟動流程分析

          作者: 時間:2012-10-25 來源:網絡 收藏

          一.引言:
          對于PC機,其開機后的初始化處理器配置、硬件初始化等操作是由BIOS(Basic Input /Output System)完成的,但對于嵌入式系統(tǒng)來說,出于經濟性、價格方面的考慮一般不配置BIOS,因此我們必須自行編寫完成這些工作的程序,這就是所需要的開機程序。而在嵌入式系統(tǒng)中,通常并沒有像 BIOS 那樣的固件程序,啟動時用于完成初始化操作的這段代碼被稱為程序,因此整個系統(tǒng)的加載啟動任務就完全由 來完成。簡單地說,通過這段程序,可以初始化硬件設備、建立內存空間的映射圖(有的CPU沒有內存映射功能如S3C44B0),從而將系統(tǒng)的軟硬件環(huán)境設定在一個合適的狀態(tài),以便為最終調用操作系統(tǒng)內核、運行用戶應用程序準備好正確的環(huán)境。依賴于實際的硬件和應用環(huán)境,因此要為嵌入式系統(tǒng)建立一個通用、標準的Bootloader是非常困難的。Bootloader也依賴于具體的嵌入式板級設備的配置,這也就是說,對于兩塊不同的嵌入式主板而言,即使它們是基于同一 CPU 而構建,要想讓運行在一塊板子上的 Bootloader 程序也能運行在另一塊板子上,通常都需要修改 Bootloader 的源程序。

          二.
          系統(tǒng)加電復位后,幾乎所有的 CPU都從由復位地址上取指令。比如,基于 7TDMI內核的CPU在復位時通常都從地址 0x00000000處取它的第一條指令。而以微處理器為核心的嵌入式系統(tǒng)通常都有某種類型的固態(tài)存儲設備(比如EEPROM、FLASH等)被映射到這個預先設置好的地址上。因此在系統(tǒng)加電復位后,處理器將首先執(zhí)行存放在復位地址處的程序。通過集成開發(fā)環(huán)境可以將Bootloader定位在復位地址開始的存儲空間內,因此Bootloader是系統(tǒng)加電后、操作系統(tǒng)內核或用戶應用程序運行之前,首先必須運行的一段程序代碼。對于嵌入式系統(tǒng)來說,有的使用操作系統(tǒng),也有的不使用操作系統(tǒng),比如功能簡單僅包括應用程序的系統(tǒng),但在系統(tǒng)啟動時都必須執(zhí)行Bootloader,為系統(tǒng)運行準備好軟硬件運行環(huán)境。
          系統(tǒng)的啟動通常有兩種方式,一種是可以直接從Flash啟動,另一種是可以將壓縮的內存映像文件從Flash(為節(jié)省Flash資源、提高速度)中復制、解壓到RAM,再從RAM啟動。當電源打開時,一般的系統(tǒng)會去執(zhí)行ROM(應用較多的是Flash)里面的啟動代碼。這些代碼是用匯編語言編寫的,其主要作用在于初始化CPU和板上的必備硬件如內存、中斷控制器等。有時候用戶還必須根據(jù)自己板子的硬件資源情況做適當?shù)恼{整與修改。
          系統(tǒng)啟動代碼完成基本軟硬件環(huán)境初始化后,對于有操作系統(tǒng)的情況下,啟動操作系統(tǒng)、啟動內存管理、任務調度、加載驅動程序等,最后執(zhí)行應用程序或等待用戶命令;對于沒有操作系統(tǒng)的系統(tǒng)直接執(zhí)行應用程序或等待用戶命令。
          啟動代碼是用來初始化電路以及用來為高級語言寫的軟件做好運行前準備的一小段匯編語言,在商業(yè)實時操作系統(tǒng)中,啟動代碼部分一般被稱為板級支持包,英文縮寫為BSP。它的主要功能就是:電路初始化和為高級語言編寫的軟件運行做準備。系統(tǒng)如圖1所示,主要的過程如下:

          基于ARM的嵌入式系統(tǒng)Bootloader啟動流程分析


          1.啟動代碼的第一步是設置中斷和異常向量。
          2.完成系統(tǒng)啟動所必須的最小配置,某些處理器芯片包含一個或幾個全局寄存器,這些寄存器必須在系統(tǒng)啟動的最初進行配置。
          3.設置看門狗,用戶設計的部分外圍電路如果必須在系統(tǒng)啟動時初始化,就可以放在這一步。
          4.配置系統(tǒng)所使用的存儲器,包括Flash,SRAM和DRAM等,并為他們分配地址空間。如果系統(tǒng)使用了DRAM或其它外設,就需要設置相關的寄存器,以確定其刷新頻率,數(shù)據(jù)總線寬度等信息,初始化存儲器系統(tǒng)。有些芯片可通過寄存器編程初始化存儲器系統(tǒng),而對于較復雜系統(tǒng)通常集成有MMU來管理內存空間。
          5.為處理器的每個工作模式設置棧指針,處理器有多種工作模式,每種工作模式都需要設置單獨的??臻g。
          6.變量初始化,這里的變量指的是在軟件中定義的已經賦好初值的全局變量,啟動過程中需要將這部分變量從只讀區(qū)域,也就是Flash拷貝到讀寫區(qū)域中,因為這部分變量的值在軟件運行時有可能重新賦值。還有一種變量不需要處理,就是已經賦好初值的靜態(tài)全局變量,這部分變量在軟件運行過程中不會改變,因此可以直接固化在只讀的Flash或EEPROM中。
          7.數(shù)據(jù)區(qū)準備,對于軟件中所有未賦初值的全局變量,啟動過程中需要將這部分變量所在區(qū)域全部清零。
          8.最后一步是調用高級語言入口函數(shù),比如main函數(shù)等。

          三.程序分析
          下面根據(jù)實際經過測試的代碼詳細講述系統(tǒng)的啟動過程。
          .text/*將此操作符開始的代碼編譯到代碼段或代碼段子段中*/
          /* 集成開發(fā)環(huán)境(IDE)可以通過鏈接腳本文件將下面的語句定位在零起始地址,系統(tǒng)上電后CPU從此處開始執(zhí)行*/
          ENTRY:
          b ResetHandler /*跳至ResetHandler,此句被定位在零起始地址*/
          /*除用戶模式外的其他6種模式稱為特權模式。特權操作模式主要處理異常和監(jiān)控調用(有時稱為軟件中斷),它們可以自由的訪問系統(tǒng)資源和改變模式。特權模式中除系統(tǒng)模式以外的5種模式又稱為異常模式,下面的代碼用于出現(xiàn)異常時CPU就會根據(jù)以下的語句自動跳轉到對應的異常處理程序處*/
          b HandlerUndef /* handlerUndef */
          b HandlerSWI /* SWI interrupt handler */
          b HandlerPabort /* handlerPAbort */
          b HandlerDabort /* handlerDAbort */
          b . /* handlerReserved */
          b HandlerIRQ
          b HandlerFIQ
          … ...
          … ...
          ResetHandler: /*上電后跳轉到此處開始執(zhí)行*/
          Ldrr0,=WTCON /*禁止看門狗*/
          ldr r1,=0x0
          str r1,[r0]
          ldr r0,=INTMSK /*屏蔽所有中斷請求 */
          ldr r1,=0x07ffffff
          str r1,[r0]


          上一頁 1 2 下一頁

          評論


          相關推薦

          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();