請教boot block到底是什么?
1.對于zlg的開發(fā)板,boot block的內容是否就是開發(fā)模板里的那些文件編譯成ELF再傳到Flash中?
2.還有用戶程序是放在Flash的哪個地方?Flash開始64字節(jié)和結尾8k字節(jié)之間?
ZLGARM:
boot block 是芯片設計廠家在LPC2000系列微控制器內部固化的一段代碼,用戶無法對其修改和刪除。這段代碼在芯片復位后首先被運行,其功能主要是判斷運行那個存儲器上的程序、檢查用戶代碼是否有效、判斷芯片是否被加密、芯片的在應用以及在系統(tǒng)編程功能。
--------------------------------------------------------------------
ARM上的Bootloader的具體實現
BootLoader簡介:
當完成用戶程序的編譯并下載到目標板上運行時,總是要首先進行存儲器的映射,然后通過 ADS(或 SDT)調試環(huán)境下載,顯然,這個過程對普通用戶來說顯得特別煩瑣,然而,要在裸板(沒有任何程序的系統(tǒng)板)上調試運行程序,也只能采用這種方法。
如果能在用戶設計的系統(tǒng)板上燒寫一段 BootLoader程序,就可以將該過程屏蔽起來,讓用戶通過一些簡單的操作,就可完成程序的下載、調試等工作。在嵌入式系統(tǒng)中,BootLoader的作用與 PC 機上的 BIOS 類似,通過 BootlLoader可以完成對系統(tǒng)板上的主要部件如 CPU、SDRAM、Flash、串行口等進行初始化,也可以下載文件到系統(tǒng)板、對 Flash 進行擦除與編程。事實上,一個功能完善的 BootLoader 已經相當于一個微型的操作系統(tǒng)了。
BootLoader 作為系統(tǒng)復位或上電后首先運行的代碼,一般應寫入 Flash 存儲器中并從起始物理地址 0x0 開始。BootLoader 根據實現的功能不同而不相同。一個簡單的 BootLoader程序可以僅僅完成串行口的初始化,并進行通信,而功能完善的 BootLoader可以支持比較復雜的命令集,對系統(tǒng)的軟硬件資源進行合理的配置與管理。因此,用戶可根據自身的需求實現相應的功能。
涉及具體匯編代碼前,有些術語要必須弄懂的
映像文件(image):指一個可執(zhí)行文件,在執(zhí)行的時候被加載到處理器中,它是ELF(Executable and Linking Format)格式的。
RO :是Read-Only的簡寫形式。一般存放的代碼
RW:是Read-Write 的簡寫形式,一般存放初始化的數據
ZI:是zero-Initialized的簡寫形式。一般是存放初始化數據
輸入段(Output Section):它包含一系列具有相同RO,RW,ZI屬性的輸入段
對于一個ARM bootloader系統(tǒng)來說,本質上,bootloader作為引導與加載內核鏡像的工具,必須提供以下幾個功能:
~1~初始化RAM(必需):bootloader應該能初始化RAM,因為將來系統(tǒng)要通過它來保存一些Volatile數據,但具體地實現要求依賴與具體的CPU以及硬件系統(tǒng)。
~2~初始化串口(可選),bootloader應該要初始化及使能一個串口,通過它與控制臺聯系進行一些debug的工作;甚至與PC通信。
~3~創(chuàng)建內核參數列表(針對linux操作系統(tǒng),推薦)。
~4~啟動內核鏡像(必需):根據內核鏡像保存的存儲介質不同,可以有兩種啟動方式:FALSH啟動以及RAM啟動;但是無論是哪種啟動方式,下面的系統(tǒng)狀態(tài)必須得到滿足:
Bootloader 階段1的代碼實現:
1,定義ARM個模式的棧大小
2,申明各模式的棧
3,將各模式的棧與棧大小結合起來,既為各棧分配棧大小
4,申明一些標號量
5,以某標號標識,一開始處設置異常中斷向量表,當冷啟動時,直接跳轉至對應處啟動
為什么在中斷向量表中不直接LDR PC,"異常地址".而是使用一個標號,然有再在后面使用DCD 定義這個標號
A:因為LDR 指令只能跳到當前PC 4kB 范圍內,而B 指令能跳轉到32MB 范圍,而現在這樣在LDR PC,"xxxx"這條指令不遠處用"xxxx"DCD 定義一個字,而這個字里面存放最終異常服務程序的地址,這樣可以實現4GB 全范圍跳轉.
如:LPC2220的復位與存儲器映射芯片復位后,MAP=00,啟動boot裝載程序,boot裝載程序檢測P0.14口的狀態(tài)和用戶的異常向量表,判斷是進入ISP還是啟動用戶程序,若啟動用戶程序,則自動設置MAP=1或3。若用戶程序需要更改異常向量表,可以將異常向量表復制到片內0x40000000,然后設置MAP=2進行重新映射,0x40000000地址上的向量表就可以更改了。
LPC2220在復位運行的第一段程序并不是用戶程序,而是boot block(引導模塊),是設計廠家在ARM內部固化的一段代碼,用戶無法修改或刪除,其主要功能為:
判斷運行那個存儲器上的程序。
檢查用戶代碼是否有效。(主要檢測異常向量表的機器碼值之和是否為0)
判斷芯片是否被加密。
芯片的在應用編程(IAP)和在系統(tǒng)編程(ISP)
boot block(包括bootload 和64字節(jié)異常向量表)。
對于LPC2220,復位后(也即是運行完Boot Block后),用戶所能見到的存儲空間,及其各存儲空間上的內容:
0xF0000000----0xFFFFFFFF:AHB外設;
0xE0000000----0xEFFFFFFF:VPB外設;
0x80000000----0xDFFFFFFF;保留給外部存儲器;
0x7FFFDFFF---0x7FFFE000;BOOT BLOCK;
0x40004000----0x4000FFFF;64KB片內RAM;
0x00000000—0x0000003f,ARM異常向量位置;
存儲器映射控制:
MAP=00:由任何硬件復位激活,boot block中斷向量映射到存儲器的底部以允許處理異常。
MAP=01:中斷向量表沒有被重新映射,它位于存儲器的底部。
MAP=10:由用戶程序激活,中斷向量表重新映射到靜態(tài)RAM的底部。
MAP=11:用戶外部模式,由BOOT[1:0]來控制存儲器的引導方式,中斷向量表重新映射到外部存儲器的底部。
例如:每當產生一個軟件中斷,ARM內核就從0x00000008處取出32位數據,當MAP=0x11時,這就意味著從0x00000008處取值既是對0x80000008處取值。存儲器重新映射控制用于改變從地址0x00000000開始的中斷向量表的映射,使就使得運行在不同存儲器空間中的代碼對中斷的控制。
拿LPC說
bootblock 出廠時固化的Loader 主要實現ISP功能!
bootloader 自己寫的程序
再到main()
上電后bootblock 檢測是否有ISP的相關引腳被設定,如果設定進入ISP模式,如果沒有設定運行用戶程序(一般來說時用戶的BootLoader),然后啟動內核或者其他的。關于異常向量表,配置好你自己的就可以了,不用管 bootblock上的!
1 設置異常中斷向量表
ARM處理器的中斷向量表從地址0x0處開始存放,連續(xù)有8×4字節(jié)的空間。在ARM存儲空間里每個字32位,占4個字節(jié)??梢酝ㄟ^圖1來描述中斷向量表的地址分配。
每當有中斷或者異常發(fā)生時,ARM處理器便強制把PC指針指向向量表中對應中斷類型的地址值。為了加快中斷響應,我們在Flash的0x0地址存放能跳轉到0x0c000008地址處中斷向量的跳轉指令,即在RAM中建立一個二級中斷向量表,起始地址為0x0c000008,除復位外,其它異常入口地址由Flash跳轉得到,如表1所示:
---------------------------------------------------
關于ARM的一些概念
3. VIC 使用注意事項
答:如果在片內RAM當中運行代碼并且應用程序需要調用中斷,那么必須將中斷向量重新映射到Flash地址0x0。這樣做是因為所有的異常向量都位于地址0x0及以上。通過將寄存器MEMMAP(位于系統(tǒng)控制模塊當中)配置為用戶RAM模式來實現這一點。用戶代碼被連接以便使中斷向量表裝載到0x4000 0000。
4. ARM啟動代碼設計
答:ARM啟動代碼直接面對處理器內核和硬件控制器進行編程,一般使用匯編語言。啟動代碼一般包括:
中斷向量表
初始化存儲器系統(tǒng)
初始化堆棧初始化有特殊要求的端口、設備
初始化用戶程序執(zhí)行環(huán)境
改變處理器模式
呼叫主應用程序
5. IRQ 和 FIQ 之間的區(qū)別
答:IRQ和FIQ是ARM處理器的兩種編程模式。IRQ是指中斷模式,FIR是指快速中斷模式。對于 FIQ 你必須盡快處理你的事情并離開這個模式。IRQ 可以被 FIQ 所中斷,但 IRQ 不能中斷 FIQ。為了使 FIQ 更快,所以這種模式有更多的影子寄存器。FIQ 不能調用 SWI(軟件中斷)。FIQ 還必須禁用中斷。如果一個 FIQ 例程必須重新啟用中斷,則它太慢了,并應該是 IRQ 而不是 FIQ。
6. ARM處理器對異常中斷的響應過程
答:ARM處理器對異常中斷的響應過程如下所述:
保存處理器當前狀態(tài)、中斷屏蔽位以及各條件標志位;
設置當前程序狀態(tài)寄存器CPSR中的相應位;
將寄存器lr_mode設置成返回地址;
將程序計數器值PC,設置成該異常中斷的中斷向量地址,跳轉到相應異常中斷處執(zhí)行。
14. 存儲器重新映射的原因:
使Flash存儲器中的FIQ處理程序,不必考慮因為重新映射所導致的存儲器邊界問題;
用來處理代碼空間中段邊界仲裁的SRAM和Boot Block向量的使用大大減少;
為超過單字轉移指令范圍的跳轉提供空間來保存常量。
ARM中的重映射是指:在程序執(zhí)行過程中,通過寫某個功能寄存器位操作,達到重新分配其存儲器地址空間的映射。一個典型的應用就是應用程序存儲在Flash/ROM中,初始這些存儲器地址是從0開始的,但這些存儲器的讀時間比SRAM/DRAM長,造成其內部執(zhí)行頻率不高,故一般在前面一段程序將代碼搬移到SRAM/DRAM中去,然后重新映射存儲器空間,將相應SRAM/DRAM映射到地址0,重新執(zhí)行程序可達到高速運行的目的。
18. VIC的基本操作如下:
答:設置IRQ/FIQ中斷,若是IRQ中斷則可以設置為向量中斷并分配中斷優(yōu)先級,否則為非向量IRQ。然后可以設置中斷允許,以及向量中斷對應地址或非向量中斷默認地址。
當有中斷后,若是IRQ中斷,則可以讀取向量地址寄存器,然后跳轉到相應的代碼。當要退出中斷時,對向量地址寄存器寫0,通知VIC中斷結束。當發(fā)生中斷時,處理器將會切換處理器模式,同時相關的寄存器也將會映射。
19. 使用外部中斷注意
把某個引腳設置為外部中斷功能后,該引腳為輸入模式,由于沒有內部上拉電阻,所以必須外接一個上拉電阻,確保引腳不被懸空;
除了引腳連接模塊的設置,還需要設置VIC模塊,才能產生外部中斷,否則外部中斷只能反映在EXTINT寄存器中;
要使器件進入掉電模式并通過外部中斷喚醒,軟件應該正確設置引腳的外部中斷功能,再進入掉電模式。
---------------------------------------------------
ARM LPC2104的Boot與Remap詳解
隨著半導體工藝技術與處理器設計技術的不斷提高,嵌入式處理器的速度愈來愈快;而非易失性存儲器的讀取速度卻遠遠跟不上CPU的發(fā)展。傳統(tǒng)的單片機運行模式中,機器代碼存儲在非易失性存儲器(如ROM,FLASH),在運行時由CPU直接從其中取出指令執(zhí)行,逐漸顯得力不從心。如果繼續(xù)沿用傳統(tǒng)的程序運行模式,那么在絕大多數時間內高速CPU將處于空閑等待狀態(tài),這既浪費了CPU的計算能力,也無法實現高密度數據流的實時處理與傳輸。而在短期之內,半導體工業(yè)界尚無法實現低成本的非易失性高速存儲器技術。為了解決上述處理器和非易失性存儲器之間速度不匹配的矛盾,工程師們在嵌入式系統(tǒng)領域內引用了Boot技術和Remap技術。而要正確理解Boot技術和Remap技術,必須先建立Memory Map(存儲器映射)的概念。
技術概念描述
Memory Map
在嵌入式處理器內,集成了多種類型的Memory,通常,我們稱同一類型的Memory為一個Memory Block。一般情況下,處理器設計者會為每一個Memory Block分配一個數值連續(xù)、數目與其存儲單元數相等、以16進制表示的自然數集合作為該Memory Block的地址編碼。這種自然數集合與Memory Block的對應關系,就是Memory Map(存儲器映射),有時也叫Address Map(地址映射)。實際上,Address Map在字面意義上更加貼切。
需要強調的是,Memory Map是一個邏輯概念,是計算機系統(tǒng)在(上電)復位后才建立起來的。 Memory Map相當于這樣一個數學函數:函數的輸入量是地址編碼,輸出量被尋址單元中的數據。當計算機系統(tǒng)掉電后或復位時,這個數學函數不復存在,只剩下計算機系統(tǒng)中實現這個數學函數的物理基礎:電路連接。也可以這樣認為:Memory Map是計算機系統(tǒng)(上電)復位時的預備動作,是一個將CPU所擁有的地址編碼資源向系統(tǒng)內各個物理存儲器塊分配的自動過程。
Boot/Bootload
Boot在計算機專業(yè)英文中的意思是“引導”,它是計算機系統(tǒng)(上電)復位后CPU的第一個機器動作。那么,Boot引導的是什么呢?簡要地說,Boot就是引導CPU如何裝入機器指令。最簡單的Boot動作就是8位單片機系統(tǒng)復位后從復位向量中取出跳轉指令,轉移到用戶程序代碼段執(zhí)行的這個過程。
通常,在計算機系統(tǒng)中,(上電)復位后除了執(zhí)行Boot動作,還跟隨著一個Load過程。一般情況下,該Load從低速非易失性存儲器中“搬運”一些數據到高速易失性存儲器中。Boot和Load連續(xù)執(zhí)行,一氣呵成,我們稱之為Bootload。最典型的例子之一就是DSP實時信號處理系統(tǒng),系統(tǒng)上電后,將存儲在EEPROM中的實時信號處理程序復制到系統(tǒng)的RAM中,然后CPU直接從RAM中讀取機器指令運行。
Remap
Remap與計算機的異常處理機制是緊密相關的。
完整的計算機系統(tǒng)必須具備異常處理能力。當異常產生時,CPU在硬件驅動機制下跳轉到預先設定的存儲器單元中,取出相應的異常處理程序的入口地址, 并根據該入口地址進入異常處理程序。這個保存有異常處理程序入口地址的存儲器單元就是通常所說的“異常入口”,單片機系統(tǒng)中也叫“中斷入口”。實際的計算機系統(tǒng)有多種類型的異常,CPU設計人員為了簡化芯片設計,一般將所有的異常入口集中起來置于非易失性存儲器中,并在系統(tǒng)上電時映射到一個固定的連續(xù)地址空間上。位于這個地址空間上的異常入口集合就是“異常向量表”。
系統(tǒng)上電后的異常向量表是從低速非易失性存儲器映射得到的。隨著處理器速度的不斷提高,很自然地,人們希望計算機系統(tǒng)在異常處理時也充分發(fā)揮出CPU的處理能力,而非易失性存儲器的讀取速度使得CPU只能以多個空閑等待同期來獲取異常向量,這樣就限制了CPU計算能力的充分發(fā)揮。尤其是非易失性存儲器位寬小于CPU位寬時,這種負面的影響更加明顯。于是,Remap技術被引入,以提高系統(tǒng)對異常的實時響應能力。
從Remap這個英文單詞的構成不難看出,它是對此前已確立的存儲器映射的再次修改。從本質上講,Map和Remap是一樣的,都是將地址編碼資源分配給存儲器塊,只不過二者產生的時間不同:前者在系統(tǒng)上電的時刻發(fā)生,是任何計算機系統(tǒng)都必需的;而后者在系統(tǒng)上電后穩(wěn)定運行的時刻發(fā)生,對計算機系統(tǒng)設計人員來說是可選的。典型的8位單片機系統(tǒng)中,就沒有使用Remap技術。
完整的Remap過程實際上通常始于系統(tǒng)的Bootload過程。具體執(zhí)行動作為:Bootload將非易失性存儲器中的異常向量復制到高速易失性存儲器塊的一端,然后執(zhí)行Remap命令,將位于高速易失性存儲器中的異常向量塊映射到異常向量表地址空間上。此后,系統(tǒng)若產生異常,CPU將從已映射到異常微量表地址空間的高速非易失性存儲器中讀取異常向量。具體到典型的ARM7嵌入式系統(tǒng)中,就是由Bootload程序將片內或片外的Flash/ROM中的異常向量復制到片內的SRAM中指定的存在器單元中,然后再執(zhí)行Remap命令。由于片內的SRAM數據位寬通常與CPU數據位寬相等,因而CPU可以無等待地全速跳入異常處理程序,獲得最佳的實時異常響應。
----------------------------------------------------
BOOT Block重映射的意義
BOOT Block是芯片設計廠家在LPC2000系列ARM內部固化的一段代碼,它在芯片復位后被首先運行,其功能主要是判斷運行哪個存儲器上的程序、檢查用戶代碼是否有效、判斷芯片是否被加密、芯片的在應用編程(IAP)以及在系統(tǒng)編程功能(ISP)。這其中有些程序是可以被用戶調用的,比如擦寫片內FLASH的IAP代碼。
為了增加用戶代碼的可移植性,所以最好能把BOOT Block的代碼固定在某個地址上。但是因為各個芯片的片內FLASH大小不盡相同,如果把BOOT Block的地址安排在片內FLASH結束的位置上,那么就無法實現BOOT Block地址的固定。所以芯片生產商把BOOT Block的地址重映射到片內存儲器空間的最高處,即接近2G(0x80000000)的地方,這樣無論片內存儲器大小如何,都不會影響B(tài)OOT Block的地址。可以讓包含有IAP操作的用戶代碼,不用修改IAP操作地址,就可以在不同的LPC2000系列ARM上運行。
-----------------------------------------------------------
ARM的存儲器映射與存儲器重映射【】
存儲器映射:是指把芯片中或芯片外的FLASH,RAM,外設,BOOTBLOCK等進行統(tǒng)一編址。即用地址來表示對象。這個地址絕大多數是由廠家規(guī)定好的,用戶只能用而不能改。用戶只能在掛外部RAM或FLASH的情況下可進行自定義。
ARM7TDMI的存儲器映射可以有0X00000000~0XFFFFFFFF的空間,即4G的映射空間,但所有器件加起來肯定是填不滿的。一般來說, 0X00000000依次開始存放FLASH——0X00000000;SRAM——0X40000000;BOOTBLOCK,外部存儲器 0X80000000;VPB(低速外設地址,如GPIO,UART)——0XE0000000;AHB(高速外設:向量中斷控制器,外部存儲器控制器) ——從0XFFFFFFFF回頭。他們都是從固定位置開始編址的,而占用空間又不大,如AHB只占2MB,所以從中間有很大部分是空白區(qū)域,用戶若使用這些空白區(qū)域,或者定義野指針,就可能出現取指令中止或者取數據中止。
由于系統(tǒng)在上電復位時要從0X00000000 開始運行,而第一要運行的就是廠家固化在片子里的BOOTBLOCK,這是判斷運行哪個存儲器上的程序,檢查用戶代碼是否有效,判斷芯片是否加密,芯片是否IAP(在應用編程),芯片是否ISP(在系統(tǒng)編程),所以這個BOOTBLOCK要首先執(zhí)行。而芯片中的BOOTBLOCK不能放在FLASH的頭部,因為那要存放用戶的異常向量表的,以便在運行、中斷時跳到這來找入口,所以BOOTBLOCK只能放在FLSAH尾部才能好找到。而ARM7的各芯片的FLASH大小又不一致,廠家為了BOOTBLOCK在芯片中的位置固定,就在編址的2G靠前編址的位置虛擬劃分一個區(qū)域作為BOOTBLOCK 區(qū)域,這就是重映射,這樣訪問<2G即<0X80000000的位置時,就可以訪問到在FLASH尾部的BOOTBLOCK區(qū)了。
BOOTBLOCK運行完,就要運行用戶自己寫的啟動代碼了,而啟動代碼中最重要的就是異常向量表,這個表是放在FLASH的頭部首先執(zhí)行的,而異常向量表中要處理多方面的事情,包括復位、未定義指令、軟中斷、預取指中止、數據中止、IRQ(中斷) ,FIQ (快速中斷),而這個異常向量表是總表,還包括許多分散的異常向量表,比如在外部存儲器,BOOTBLOCK,SRAM中固化的,不可能都由用戶直接定義,所以還是需要重映射把那些異常向量表的地址映到總表中。
為存儲器分配地址的過程稱為存儲器映射,那么什么叫存儲器重映射呢?為了增加系統(tǒng)的靈活性,系統(tǒng)中有部分地址可以同時出現在不同的地址上,這就叫做存儲器重映射。重映射主要包括引導塊“Boot Block”重映射和異常向量表的重映射。
1.引導塊“Boot Block”及其重映射
Boot Block是芯片設計廠商在LPC2000系列ARM內部固化的一段代碼,用戶無法對其進行修改或者刪除。這段代碼在復位時被首先運行,主要用來判斷運行哪個存儲器上面的程序,檢查用戶代碼是否有效,判斷芯片是否被加密,系統(tǒng)的在應用編程(IAP)以及在系統(tǒng)編程功能(ISP)等。
Boot Block存在于內部Flash,LPC2200系列大小為8kb,它占用了用戶的Flash空間,但也有其他的LPC系列不占用FLash空間的,而部分沒有內部Flash空間的ARM處理器仍然存在Boot Block。
重映射的原因:
Boot Block中有些程序可被用戶調用,如擦寫片內Flash的IAP代碼。為了增加用戶代碼的可移植性,所以最好把Boot Block的代碼固定的某個地址上。但由于各芯片的片內Flash大小不盡相同,如果把Boot Block的地址安排在內部Flash結束的位置上,那就無法固定Boot Block的地址。
為了解決上面的問題,于是芯片廠家將Boot Block的地址重映射到片內存儲器空間的最高端,即接近2Gb的地方,這樣無論片內存儲器的大小如何,都不會影響B(tài)oot Block的地址。因此當Boot Block中包含可被用戶調用的IAP操作的代碼時,不用修改IAP的操作地址就可以在不同的LPC系列的ARM上運行了。
2.異常向量表及其重映射
ARM內核在發(fā)生異常后,會使程序跳轉到位于0x0000~0x001C的異常向量表處,再經過向量跳轉到異常服務程序。但ARM單條指令的尋址范圍有限,無法用一條指令實現4G范圍的跳轉,所以應在其后面的“0x0020~0x003F”地址上放置跳轉目標,這樣就可以實現4G范圍內的任意跳轉,因此“一個異常向量表實際上占用了16個字的存儲單元”。以下為一張中斷向量表:
LDR PC, ResetAddr
LDR PC, UndefinedAddr
LDR PC, SWI_Addr
LDR PC, PrefetchAddr
LDR PC, DataAbortAddr
DCD 0xb9205f80
LDR PC, [PC, #-0xff0]
LDR PC, FIQ_Addr
ResetAddr DCD ResetInit
UndefinedAddr DCD Undefined
SWI_Addr DCD SoftwareInterrupt
PrefetchAddr DCD PrefetchAbort
DataAbortAddr DCD DataAbort
Nouse DCD 0
IRQ_Addr DCD 0
FIQ_Addr DCD FIQ_Handler
重映射的原因:
由于ARM處理器的存儲器結構比較復雜,可能同時存在片內存儲器和片外存儲器等,他們在存儲器映射上的起始地址都不一樣,因此ARM內核要訪問的中斷向量表可能不在0x0000~0x003F地址上,因此采用了存儲器重映射來實現將存在與不同地方的中斷向量表都映射到0x0000~0x003F地址上。
注意:Boot Block 也存在中斷向量表,而且復位后這段代碼首先映射到 0x0000~0x003F地址上,也就是說復位后首先運行的是Boot Block程序。各個存儲區(qū)域的中斷向量表也不盡相同。