生活随笔
收集整理的這篇文章主要介紹了
Scatter文件编写
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
(和《ARM嵌入式應(yīng)用技術(shù)基礎(chǔ)》186-190頁一模一樣) ?
Scatter 文件編寫 ?一個映像文件中可以包含多個域(region),在加載和運(yùn)行映像文件時,每個域可以有不同的地址。每個域可以包括多達(dá)3個輸出段,每個輸出段是由若干個具有相同屬性的輸入段組成。這樣在生成映像文件時,ARM鏈接器就需要知道下述兩個信息。
分組信息??? 決定各域中的輸出段是由哪些輸入段組織而成; 定位信息??? 決定各域在存儲空間中的起始地址。 根據(jù)映像文件中地址映射的復(fù)雜程度,有兩種方法來告訴ARM鏈接器這些相關(guān)的信息。對于映像文件中地址映射關(guān)系比較簡單的情況,可以使用命令行選項;對于映像文件中地址映射關(guān)系比較復(fù)雜的情況,可以使用一個scatter配置文件。Scatter文件又稱為分散加載文件,將重點(diǎn)講解如何編寫scatter文件。
1 、Scatter文件結(jié)構(gòu) Scatter文件是一個文本文件,使用BNF語法來描述ARM鏈接器生成映像文件時所需要的信息。具體來說,在scatter文件中可以指定下列信息:
各個加載時域的加載時起始地址、最大尺寸和屬性; 每個加載時域包含的輸出段; 各個輸出段的運(yùn)行時起始地址、最大尺寸、存儲訪問特性和屬性; 各個輸出段中包含的輸入段。 一個Scatter文件包含若干個加載域,一個加載域包含若干個輸出段,一個輸出段由若干個具有相同屬性的輸入段組成,其結(jié)構(gòu)如圖1所示
?
圖1 Scatter文件結(jié)構(gòu)示意圖
? ? ①? 加載時域的描述 加載時域包括名稱、起始地址、屬性、最大尺寸和一個運(yùn)行時域的列表。使用BNF語法描述,加載時域的格式如下所示:
Load_name ???? base_designator??? ???? attribute ???? max_size{…… }
Load_name?? 運(yùn)行時域名稱,它除了唯一地標(biāo)識一個運(yùn)行時域外,還用來構(gòu)成鏈接器生成的鏈接符號; base_designator 用來表示本加載時域的起始地址,它可以有兩種格式表示:起始地址或偏移量;? attribute?? 本加載時域的屬性,其可能的取值為下面之一,默認(rèn)的取值為ABSOLUTE: ??? PI ???????? 位置無關(guān)屬性; ??? RELOC ????? 重定位; ??? ABSOLUTE ?? 絕對地址;? max_size 最大尺寸,如果本加載時域的實際尺寸超過了該值,鏈接器將報告錯誤。默認(rèn)的取值為0xFFFFFFFF。 ??? ②? 輸出段的描述 輸出段包括名稱、起始地址、屬性、最大尺寸和一個輸入段的集合。使用BNF語法描述,輸出段的格式如下所示:
output_name ??? base_designator ??? attribute?? ??? max_size{…… }
output_name 輸出段的名稱,它用來唯一地標(biāo)識一個輸出段,還用來構(gòu)成鏈接器生成的鏈接符號。 base_designator 用來表示本輸出段的起始地址,它可以有兩種格式:起始地址值或偏移量。 attribute?? 表示本輸出段的屬性,其可能的取值如下所示: ????PI????????? 位置無關(guān)屬性 ??? RELOC?????? 重定位 ??? ABSOLUTE??? 絕對地址 ??? FIXED?????? 固定地址 ??? UNINIT ???? 未初始化的數(shù)據(jù) max_size??? 指定本輸出段的最大尺寸。 ??? ③? 輸入段的描述 輸入段里描述了一個文本字符串的模式,匹配該模式的輸入段都將被包含在當(dāng)前域中。模式中可以使用匹配符,符號"*"代表零個或者多個字符,符號"?"代表單個字符。進(jìn)行匹配時,所有字符是大小寫無關(guān)的。下面介紹一些使用scatter文件配置映像文件地址映射模式的例子。在本例中,映像文件包括一個加載時域和3個連續(xù)的輸出段,這種模式適合于那些將其他程序加載到RAM中的程序,如操作系統(tǒng)的引導(dǎo)程序和Angel等。例子??? 一個簡單的scatter文件?
Load_1?? 0x4000???????????? ;定義加載時域的名稱為Load_1,起始地址為0x4000{ER_RO??? + 0???? ;輸出段名ER_RO,地址偏移量0,所以起始地址為0x4000{ *( + RO) }?????? ;通配符*,包含了所有的RO屬性的輸入段,它們被連續(xù)放置ER_RW??? + 0???? ;輸出段名稱ER_RW,起始地址為前一個輸出段的結(jié)束地址加偏移量0{ *( +? RW) }????? ;本輸出段包含所有的RW屬性的輸入段,它們被連續(xù)放置ER_ZI 0x5000?????? ;輸出段名稱ER_ZI,起始地址為0x5000{ *( +? ZI) }????? ;本輸出段包含了所有的ZI屬性的輸入段,它們被連續(xù)放置}
按照例 scatter文件的描述,ARM鏈接器會生成相應(yīng)的映像文件地址映射關(guān)系,如圖2所示。
?
圖2 程序運(yùn)行時地址映射關(guān)系
?
2 、固定時域 任何一個映像文件都需要指定一個初始入口點(diǎn)(initial entry point),它是影響文件運(yùn)行時的入口點(diǎn)。初始入口點(diǎn)必須位于一個固定域中,所謂固定域是指該域的加載時地址和運(yùn)行時地址是相同的。如果初始入口點(diǎn)不是位于一個固定域中,ARM鏈接器在鏈接時會產(chǎn)生下面的錯誤信息。L6203E:Entry point (0x0000 0000) lies within non-root region 32 bit RAM使用scatter文件時,可以有下面兩種方法來設(shè)置固定域。
??? ①? 設(shè)置輸出段地址 第1種方法是設(shè)定一個加載域中第1個輸出段的運(yùn)行地址,使其和該加載域的加載地址相同。這樣該輸出段就是一個固定域。例1就使用這種方法確定固定域。其中,加載域LR_1的起始地址為0x8000,輸出段ER_RO的起始地址指定為0x8000,與加載域LR_1的起始地址相同,因此,輸出段ER_RO是一個固定域,并且是映像文件的初始入口點(diǎn)。例1 指定固定域
LR_1 0x08000??????????????? ;加載域LR_1的起始地址為0x8000{ER_RO 0x08000????????? ;輸出段ER_RO的起始地址為0x8000{*( +? RO)????????? ;包含了所有的RO數(shù)據(jù),包含初始入口點(diǎn)};其他部分內(nèi)容}
??? ②? 設(shè)置輸出段屬性 第2種方法通過將某個輸出段的屬性設(shè)置成FIXED。例2指定固定域
LR_1 0x8000???????????????? ;加載時域LR_1的起始地址為0x8000{ER_RO??? 0x8000{*( +? RO)????????? ;除了init.o之外的其他RO數(shù)據(jù)}ER_INIT 0x9000 FIXED?? ;設(shè)置輸出段屬性為FIXED,確定固定域{init.o( +? RO)???????? ;本輸出段包含了init.o,包含映像文件的初始入口點(diǎn)};其他部分內(nèi)容}
?
3 、一個實際系統(tǒng)的例子 在一個嵌入式設(shè)備中,為了保持好的性價比,通常在系統(tǒng)中存在多種存儲器。在一個實際的ARM開發(fā)板中,可能包括片內(nèi)Flash、RAM和片外Flash、RAM。在本例中,我們假設(shè)用ARM芯片構(gòu)造了一個嵌入式系統(tǒng),包含了8KB片內(nèi)Flash存儲器、16KB片內(nèi)RAM存儲器、起始地址為0x80000000的片外Flash和起始地址為0x81000000的片外RAM,其地址空間分配關(guān)系如圖3所示。在這樣的ARM系統(tǒng)中,我們編寫了程序,并且按照例3中的分散加載文件對映象文件的地址進(jìn)行分配。分配后的地址映像關(guān)系如圖4所示。
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
?
圖3 ARM系統(tǒng)中的地址空間 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖4 地址映像關(guān)系從圖4中可以看出:可執(zhí)行代碼都放在片外Flash中,并且Vectors向量表放在片外Flash的起始地址上;Startup目標(biāo)文件的數(shù)據(jù)放置在片內(nèi)RAM中,堆棧放在片內(nèi)RAM的頂端;其他數(shù)據(jù)放置在片外RAM中,堆空間緊跟其后。例3 片外Flash啟動程序的scatter文件
ROM_LOAD ?0x80000000???????????????? ;定義加載區(qū)名稱ROM_LOAD,起始地址0x80000000{ROM_EXE? 0x80000000????????????? ;定義執(zhí)行代碼空間,起始地址與加載域地址相同{Startup.o (vectors,? +First)???? ;首先放置Startup.o文件的向量表vectors* ( +RO)?????????????? ;后面地址空間放置其他RO屬性代碼}?IRAM ?0x40000000???????????????????? ;定義數(shù)據(jù)空間{?? Startup.o ( +RW, +ZI) ? }STACKS? 0x40004000? UNINIT?????????? ;定義堆棧空間{??? stack.o ( +ZI)??? }ERAM? 0x81000000???????????????????? ;定義數(shù)據(jù)空間{?? * ( +RW, +ZI)????? }???????????? ;剩下未指定空間的所有數(shù)據(jù)HEAP + 0? UNINIT???????????????????? ;定義堆空間{???? heap.o ( +ZI)??? }
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/liuchengchuxiao/p/4171427.html
總結(jié)
以上是生活随笔 為你收集整理的Scatter文件编写 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔 推薦給好友。