<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > ARM7嵌入式系統中Bootloader分析與設計

ARM7嵌入式系統中Bootloader分析與設計

作者: 時(shí)間:2016-11-11 來(lái)源:網(wǎng)絡(luò ) 收藏
1.引言

作為一種16/32位的高性能、低成本、低功耗嵌入式RISC(Reduced Instruction Set Computer)微處理器,ARM(Advanced RISC Machines )微處理器目前已經(jīng)成為應用最為廣泛的嵌入式微處理器[1]。在嵌入式系統開(kāi)發(fā)中Bootloader常常是嵌入式系統開(kāi)發(fā)中可能遇到的第一個(gè)技術(shù)難點(diǎn)。應用程序運行環(huán)境能否正確構建,內核能否啟動(dòng)成功,都取決于Bootloader能否正確的工作。一個(gè)功能完善的嵌入式系統Bootloader還要求能夠提供系統更新的能力,以及為了實(shí)現這一操作所需要的一個(gè)簡(jiǎn)單的命令控制臺。本文在基于ARM7-uClinux嵌入式系統的硬件平臺和軟件平臺基礎上,描述了系統引導程序Bootloader的設計原理,闡述了設計時(shí)應考慮的因素和需解決的技術(shù)難點(diǎn)并給出了一套可行的引導程序流程。

本文引用地址:http://dyxdggzs.com/article/201611/316977.htm

2.系統組成

典型的ARM嵌入式系統硬件平臺一般包括一個(gè)以ARM為內核的處理器、存儲器和必要的外部接口與設備。在本系統中采用內嵌ARM7TDMI的Samsung公司S3C4510B處理器,存儲器使用2MB的Flash和16MB的SDRAM,外部接口除了可用于下載和通信的串口,還配備了一個(gè)以太網(wǎng)接口以支持S3C4510B的網(wǎng)絡(luò )功能。

軟件平臺由系統引導程序、嵌入式操作系統內核和文件系統組成,系統引導程序通常即指我們這里的Bootloader,其代碼量雖少但是作用非常大,相當于普通PC機中的BIOS。通過(guò)Bootloader,我們可以初始化硬件設備、建立內存空間的映射圖,從而將系統的軟硬件環(huán)境帶到一個(gè)合適的狀態(tài),以便為最終調用操作系統內核準備好正確的環(huán)境。

3.Bootloader 設計分析

3.1 Bootloader 的操作模式 (Operation Mode)

大多數 Bootloader 都包含兩種不同的操作模式[2]:

(1). 啟動(dòng)加載(Boot loading)模式:也稱(chēng)為“自主”模式。即Bootloader 從目標機上的某個(gè)固態(tài)存儲設備上將操作系統加載到 RAM 中運行,整個(gè)過(guò)程并沒(méi)有用戶(hù)的介入。

(2).下載(Downloading)模式:在這種模式下,目標機上的Bootloader將通過(guò)串口或網(wǎng)絡(luò )連接等通信手段從主機(Host)下載內核映像和根文件系統映像等,然后保存到目標機上的FLASH 類(lèi)固態(tài)存儲設備中。Bootloader的這種模式通常在系統初次安裝和更新時(shí)被使用,工作于這種模式下的Bootloader通常都會(huì )向它的終端用戶(hù)提供一個(gè)簡(jiǎn)單的命令行接口。

在我們的Bootloader設計中我們同時(shí)支持這兩種工作模式,采用的方法是:一開(kāi)始啟動(dòng)時(shí)處于正常的啟動(dòng)加載模式,但并不立即啟動(dòng)進(jìn)入uClinux內核,而是提示延時(shí)5秒,等待終端用戶(hù)如果按下某一特定按鍵,則切換到下載模式,否則繼續啟動(dòng)uCLinux 內核。

3.2 Bootloader 的啟動(dòng)及初始化

基于A(yíng)RM的芯片多數為復雜的片上系統(SoC),這類(lèi)復雜系統里的多數硬件模塊都是可配置的[3]。因此大多數 Bootloader 都分為 stage1 和 stage2 兩大部分。依賴(lài)于 CPU 體系結構的代碼,通常都放在 stage1 中,而且在這一部分,我們直接對處理器內核和硬件控制器進(jìn)行編程,因此常常都用匯編語(yǔ)言來(lái)實(shí)現。而stage2則通常用C語(yǔ)言來(lái)實(shí)現,這樣可以實(shí)現更復雜的功能,而且代碼會(huì )具有更好的可讀性和可移植性。

3.2.1 Bootloader的stage1

這部分代碼必須首先完成一些基本的硬件初始化,為stage2的執行以及隨后的kernel 的執行準備好一些基本的硬件環(huán)境[2]。Bootloader的stage1一般通用的內容包括:

* 定義程序入口點(diǎn)

* 設置異常向量表

* 初始化存儲系統(包括地址重映射)

* 初始化有特殊要求的端口,設備

* 初始化用戶(hù)程序的執行環(huán)境

* 初始化堆棧指針寄存器,必要時(shí)改變處理器的模式

* 設置FIQ/IRQ中斷處理程序入口

* 進(jìn)入C程序

在整個(gè)Bootloader的初始化過(guò)程中我們都不必響應中斷,因此首先禁止系統的中斷,然后程序設置CPU的速度和時(shí)鐘頻率,設置CPU內部指令/數據cache,DRAM初始化,DRAM初始化完成后即可拷貝ROM中的代碼到DRAM中,然后內存重映射,程序開(kāi)始進(jìn)入DRAM中執行,然后再初始化一些用戶(hù)有特殊要求的端口、設備,比如LED或串口等,可以通過(guò)點(diǎn)亮LED,或者向串口打印一些調試信息,以此表明系統的狀態(tài)是OK還是Error。然后準備進(jìn)入C語(yǔ)言代碼:拷貝Bootloader的RW/RO 段到相應的運行位置,初始化ZI段,初始化系統堆棧,設置FIQ/IRQ中斷處理程序入口,設置完成就可以進(jìn)入到C代碼了。

3.2.2 Bootloader的stage2

為了讓程序跳入C語(yǔ)言的“main”函數,我們采用直接將pc指針指向“main”函數的方法,實(shí)現代碼如下:

[ THUMBCODE ; [ = IF , 如果是匯編Thumb代碼,則采用bx指令跳轉

bx lr

| ; | = ELSE

mov pc, lr ; 匯編ARM代碼,則直接跳轉到main函數

] ; ] = ENDIF

進(jìn)入main函數后即可以開(kāi)始本階段stage2的初始化任務(wù),這包括:

(1)初始化至少一個(gè)串口,以便和終端用戶(hù)進(jìn)行交互;

(2)初始化計時(shí)器,延時(shí)并提示啟動(dòng)模式的選擇,如果進(jìn)入啟動(dòng)加載模式,則系統控制權交由uClinux操作系統,Bootloader功成身退,否則程序繼續向下執行。

(3)初始化網(wǎng)絡(luò ),包括網(wǎng)絡(luò )基本信息配置等;

(5)如果系統配有LCD等外設,可以在此初始化;

(6)初始化Flash:檢測是否支持該Flash芯片(可通過(guò)比較Flash ID的方式實(shí)現);

(7)初始化中斷,包括屏蔽中斷,清除中斷懸掛標志,初始化中斷向量表,注冊需要的中斷處理函數等。

(8)初始化命令控制臺,等待用戶(hù)鍵入命令。

在初始化這些設備之前,也可以改變 LED 燈的狀態(tài),以表明我們已經(jīng)進(jìn)入main函數執行。設備初始化完成后,可以通過(guò)串口輸出一些打印信息,如程序名字字符串、版本號等。本系統中采用的系統啟動(dòng)引導方案流程圖如圖1所示。

4.難點(diǎn)分析

4.1異常及中斷處理

在A(yíng)RM支持的7種模式中,共有5種異常模式,而其中又尤以外部中斷模式(IRQ)應用較為廣泛,其異常處理過(guò)程也較為復雜。本文下面將以IRQ異常處理為例,講述一個(gè)通用的中斷使用及處理過(guò)程。一個(gè)ARM通用的中斷處理過(guò)程大致可以分為以下3步:

(1) 異常響應:獲取異常處理程序入口地址,并進(jìn)入異常處理程序;

(2) 現場(chǎng)保護及恢復:即進(jìn)入中斷服務(wù)程序(ISR)前后中斷現場(chǎng)的保護和恢復;

(3) 中斷服務(wù):計算中斷源索引號,清中斷,然后進(jìn)入中斷服務(wù)。

本例中IRQ異常處理相關(guān)代碼如下:

ResetEntry

b SYS_RST_HANDLER ;復位異常

......

b IRQ_SVC_HANDLER ;外部中斷請求

MACRO ;通過(guò)一個(gè)宏定義,統一處理各異常處理程序與異常向量地址的映射關(guān)系

$HandlerLabel HANDLER $ExceptHandler

$HandlerLabel

sub sp,sp,#4 ;預留一個(gè)字的空間用來(lái)保存PC的跳轉地址

stmfd sp!,{r0} ;保存下面中斷處理中使用到的r0寄存器

ldr r0,=$ExceptHandler ;將保存有異常處理函數入口的地址讀入r0

ldr r0,[r0] ;將異常處理函數入口讀入r0

str r0,[sp,#4] ;將異常處理函數入口存入堆棧中剛才預留的空間

ldmfd sp!,{r0,pc} ;恢復現場(chǎng),同時(shí)跳入異常處理函數

MEND

IRQ_SVC_HANDLER HANDLER IrqSvcVector ;調用宏定義

......

SYS_RST_HANDLER ;復位異常時(shí)程序跳轉地址

...... ;系統初始化代碼

ldr r0, =IrqSvcVector

ldr r1, =IRQ_SERVICE

str r1, [r0] ;將IRQ異常處理程序入口存入變量IrqSvcVector

......

IRQ_SERVICE

STMFD sp!, {r0-r12, lr}

BL ISR_IrqHandler ;跳入C語(yǔ)言中定義的中斷服務(wù)程序(ISR)

LDMFD sp!, {r0-r12, lr}

SUBS pc, lr, #4 ;異常返回同時(shí)復制相應SPSR到CPSR,實(shí)現處理器模式自動(dòng)切換

void ISR_IrqHandler(void) //C語(yǔ)言中定義的中斷服務(wù)程序

{

unsigned int IntOffSet;

IntOffSet = (unsigned int)inl(INTOFFSET);//取出中斷源索引號

Clear_PendingBit(IntOffSet>>2); //清中斷

(*InterruptHandlers[IntOffSet>>2])(); // 進(jìn)入對應的中斷服務(wù)子函數

}

從上面的代碼我們可以總結得出,接收到IRQ中斷請求后程序的執行流程是:

(1)執行完當前指令,程序自動(dòng)跳到0x18地址;

(2)從0x18 程序跳轉到IRQ_SVC_HANDLER;

(3)從IRQ_SVC_HANDLER 再到SDRAM高端異常矢量表;

(4)從SDRAM高端異常矢量表跳轉到IRQ_SERVICE異常處理程序;

(5)由IRQ_SERVICE最后進(jìn)入中斷服務(wù)程序,完成中斷處理任務(wù)后返回。

4.2 命令控制臺

當Bootloader工作在下載模式時(shí),通常會(huì )通過(guò)串口向終端用戶(hù)提供一個(gè)簡(jiǎn)單的命令控制臺,為了使用的方便,我們這里對其功能進(jìn)行了擴充,添加了命令鍵入時(shí)對鍵盤(pán)“上、下、左、右、Home、End”幾個(gè)方向鍵的支持。

通過(guò)串口收發(fā)或顯示字符時(shí),我們使用的通常是字符的ASCII碼。對于非控制字符,也即鍵入命令時(shí)我們可能使用到的命令字符,在控制臺中我們使用了ASCII碼值從0x20~0x7e之間的字符。對于控制字符,在常用字符ASCII碼對照表中我們可以找到Enter鍵、Backspace(退格)鍵以及ESC鍵的ASCII碼,但是卻沒(méi)有上下左右方向鍵以及Home、End鍵對應的ASCII碼,通過(guò)對鍵盤(pán)輸入字符的串口收發(fā)測試發(fā)現,如果在測試時(shí)按下了方向鍵則串口在每次按鍵后會(huì )連續發(fā)送出3字節數據,前兩字節所有方向鍵的數據相同,分別是0x1b,0x5b,第3字節對應不同的按鍵,上下右左方向鍵分別對應的值為:0x41、0x42、0x43、0x44,Home和End鍵對應的值為0x48和0x4b。故要檢測鍵盤(pán)是否鍵入了方向鍵,需要向串口連續讀取三字節的數據,同理,要控制光標向左、向右移動(dòng)或Home、End也需要連續一次向串口發(fā)送3字節數據。命令控制臺從串口接收到字符后,程序處理的流程圖如圖2所示。

5.結束語(yǔ)

Bootloader與具體的硬件環(huán)境和操作系統是緊密聯(lián)系在一起,針對某個(gè)CPU芯片編寫(xiě)Bootloader代碼,首先要了解該CPU的內核結構、指令系統,其次是具體芯片的結構和各種片上資源,以及所采用的操作系統。本文給出的Bootloader代碼已經(jīng)在基于Samsung公司的S3C4510B芯片開(kāi)發(fā)的系統板上運行并測試通過(guò)。該Bootloader能夠正常引導及更新uClinux內核,系統運行穩定,完全實(shí)現了設計目的,達到了嵌入式系統的設計要求。

參考文獻:

[1]. 李駒光等.ARM應用系統開(kāi)發(fā)詳解——基于S3C4510B的系統設計. 清華大學(xué)出版社.2003 .

[2]. 詹榮開(kāi). 嵌入式系統Bootloader技術(shù)內幕.

http://linux.chinaunix.net/doc/embedded/2005-01-13/762.shtml

[3]. 蔡治等.基于A(yíng)RM核的嵌入式應用系統中的啟動(dòng)代碼的編程.電子科技,NO6,2005



關(guān)鍵詞: ARM7Bootloade

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>