關(guān)于LPC2200啟動(dòng)程序分散加載描述文件的敘述
分散裝在技術(shù)概述:
本文引用地址:http://cafeforensic.com/article/201611/317887.htm分散裝在技術(shù)可以把用戶的應(yīng)用程序分割成多個(gè)RO(只讀)運(yùn)行域和RW(可讀寫)運(yùn)行域(關(guān)于域的概念大家可以在網(wǎng)上查查),并且給它們制定不同的地址。一個(gè)嵌入式系統(tǒng)中,F(xiàn)lash、16位RAM、32位RAM都可以存在于系統(tǒng)中,所以,將不同功能的代碼定位在特定的位置會(huì)大大地提高系統(tǒng)的運(yùn)行效率。下面是最為常用的2種情況:
一、32位的RAM運(yùn)行速度很快,因此就把中斷服務(wù)程序作為一個(gè)單獨(dú)的運(yùn)行域,放在32位的RAM,使它的響應(yīng)時(shí)間達(dá)到最快。
二、程序在RAM中運(yùn)行,其效率要遠(yuǎn)遠(yuǎn)高于在ROM中運(yùn)行,所以將啟動(dòng)代碼(Boot loader)以外的所有代碼都在RAM中運(yùn)行,可以提高運(yùn)行效率。
分散裝在技術(shù)主要完成了2個(gè)基本的功能:
如何分散。就是如何將輸入段組成輸出段和域。
如何裝載。就是確定裝載域和滅個(gè)運(yùn)行域在存儲(chǔ)空間里的地址是多少。
域可以分為裝載域和運(yùn)行域
裝載域描述運(yùn)行前輸出段和域在ROM/RAM里的分布狀態(tài),運(yùn)行域描述了運(yùn)行時(shí)輸出段和域在ROM/RAM里的分布狀態(tài)。大多數(shù)情況下,映像文件哎執(zhí)行前把它裝載到ROM里,而當(dāng)運(yùn)行時(shí),域里的有些輸出段(比如RW類型的輸出段)必須到RAM里,程序才能正常運(yùn)行,所以,在裝載和運(yùn)行時(shí),RW類的輸出段處在不同的位置(地址空間)。
Scatterfile分散加載文件:
在scatterfile中可以為每一個(gè)代碼或數(shù)據(jù)區(qū)在裝載和執(zhí)行時(shí)指定不同的存儲(chǔ)區(qū)域地址,Scatlertoading的存儲(chǔ)區(qū)塊可以分成二種類型:
裝載區(qū):當(dāng)系統(tǒng)啟動(dòng)或加載時(shí)應(yīng)用程序的存放區(qū)。
執(zhí)行區(qū):系統(tǒng)啟動(dòng)后,應(yīng)用程序進(jìn)行執(zhí)行和數(shù)據(jù)訪問的存儲(chǔ)器區(qū)域,系統(tǒng)在實(shí)時(shí)運(yùn)行時(shí)可以有一個(gè)或多個(gè)執(zhí)行塊。
映像中所有的代碼和數(shù)據(jù)都有一個(gè)裝載地址和運(yùn)行地址(二者可能相同也可能不同,視具體情況而定)。
scatter文件語(yǔ)法
scatter文件是一個(gè)簡(jiǎn)單的文本文件,包含一些簡(jiǎn)單的語(yǔ)法。
My Region 0x0000 0x1000
{
;the context of region
}
標(biāo)題
每個(gè)塊由一個(gè)頭標(biāo)題開始定義,頭中至少包含塊的名字和起始地址,如(0x0000),另外還有最大長(zhǎng)度等其他一些屬性選項(xiàng)(注:這些屬性是可選的,如0x1000)。
內(nèi)容
塊定義的內(nèi)容包括在緊接的一對(duì)花括號(hào)內(nèi),依賴于具體的系統(tǒng)情況。
一個(gè)加載塊必須至少含有一個(gè)執(zhí)行塊;實(shí)踐中通常有多個(gè)執(zhí)行塊。
一個(gè)執(zhí)行塊必須至少含有一個(gè)代碼或數(shù)據(jù)段;這些通常來自源文件或庫(kù)函數(shù)等的目標(biāo)文件;通配符號(hào)*可以匹配指定屬性項(xiàng)中所有沒有在文件中定義的余下部分。
有以下幾種屬性:
RO:只讀的代碼段和常量
RW:可以讀寫的全局變量和靜態(tài)變量
ZI:RW段中要被初始化為零的變量。
Scatterfile中的定義要按照系統(tǒng)沖定向后的存儲(chǔ)器分布情況進(jìn)行,在引導(dǎo)程序完成初始化任務(wù)后,應(yīng)該把主程序轉(zhuǎn)移到RAM中運(yùn)行以加快系統(tǒng)的運(yùn)行速度。
LPC2200分散加載文件分析:
ROM_LOAD 0x80000000 (1)
{
ROM_EXEC 0x80000000 (2)
{
Startup.o (vectors, +First) (3)
* (+RO) (4)
}
IRAM 0x40000000 (5)
{
Startup.o (MyStacks) (6)
}
STACKS_BOTTOM +0 UNINIT (7)
{
Startup.o (StackBottom) (8)
}
STACKS 0x40004000 UNINIT (9)
{
Startup.o (Stacks) (10)
}
ERAM 0x80040000 (11)
{
* (+RW,+ZI) (12)
}
HEAP +0 UNINIT (13)
{
Startup.o (Heap) (14)
}
HEAP_BOTTOM 0x80080000 UNINIT (15)
{
Startup.o (HeapTop) (16)
}
}
FLASH_LOAD 0x81000000 0x1000 (17)
{
FLASH_EXEC 0x81000000 (18)
{
main.o (+RO) (19)
}
}
(1)加載時(shí)域描述,名稱位ROM_LODA 它的地址為0x80000000;0x80000000為L(zhǎng)PC片外RAM地址,即將以下的加載的段和域都在RAM中。
(2)第一個(gè)運(yùn)行時(shí)域描述。ROM_EXEC描述了執(zhí)行區(qū)的地址,放在第一塊定義,其起始地址、空間大小域加載區(qū)起始地址、空間大小要一樣。
(2)-(4)從起始地址開始放置向量表。Startup.o是Startup.s的目標(biāo)文件。Vectors為中斷向量表。模塊Startup位于該加載域的開頭(+First),vectors作為入口點(diǎn),包含全部的RO代碼。ARM在芯片復(fù)位之后,系統(tǒng)進(jìn)入管理模式、ARM狀態(tài),PC(R15)寄存器的值為0x00000000,所以必須保證用戶的向量表代碼定位在0x00000000處,或者映射到0x00000000處(例如向量表代碼在0x80000000處,通過存儲(chǔ)器映射,訪問0x0000000就是訪問0x80000000)。
(5)-(6)第二運(yùn)行時(shí)域描述。將MyStacks堆棧段裝載到片內(nèi)靜態(tài)RAM中。
(7)-(8)將棧底放入堆棧的后面(+0)不進(jìn)行初始化(UNINIT), 棧底為Startup中的StackBottom。
(9)-(10) 將棧放入地址為0x40004000 并且不進(jìn)行初始化(UNINIT)。
(11)-(12將所有的RW和ZI段放入外部存儲(chǔ)器中以0x80040000為開頭的地址中。并且全部清零(+ZI)外部RAM中指定的區(qū)域。
(13)-(14)在RW ZI段后放入堆底(Startup.o(Heap))并且不進(jìn)行初始化。
(15)-(16)將堆定放入外部RAM中(0x80080000)。
(17)-(19)自己添加的加載代碼,把main.c的目標(biāo)文件加載到片外Flash中并且占用了0x1000的大小。
評(píng)論