嵌入式軟件開發(fā)之: 映像文件存儲器映射調(diào)整
如果對輸入段的排列順序有特殊的要求,如特定的輸入段必須是域中的第一個輸入節(jié),而包含校驗和的輸入段必須是最后一個輸入段,可以使用FIRST和LAST標記執(zhí)行區(qū)中的第一個和最后一個段。
FIRST或LAST偽屬性必須放在屬性列表的最后。
特殊的模塊選擇程序模式“.ANY”允許在不考慮其父模塊的情況下,將輸入段分配給執(zhí)行域。使用一個或多個“.ANY”模式以任意分配方式填充執(zhí)行域。在大多數(shù)情況下,使用單個“.ANY”相當于使用“*”模塊選擇屬性。
在分散載入描述文件中不能使用兩個“*”選擇屬性。但是,可以使用兩個變形的選擇程序,例如,*A和*B,也可以將.ANY選擇屬性與模塊選擇屬性一起使用。*模塊選擇屬性的優(yōu)先級比.ANY高。如果刪除了文件中包含*選擇屬性的部分,.ANY選擇屬性才能在鏈接時起作用。
在解析所有其他(非.ANY)輸入段描述并且將輸入段分配給最匹配的執(zhí)行區(qū)之后,才解析使用.ANY模塊選擇程序模式的input_section_descriptions。如果有一個以上.ANY模式,則鏈接程序盡可能多地填充第一個.ANY,然后開始填充下一個.ANY。
每個未被分配的剩余輸入段將被分配給具有以下特性的執(zhí)行區(qū):
· 最大的剩余空間(由max_size的值和已分配給該區(qū)的輸入段的尺寸確定);
· 匹配.ANY的input_section_description;
· 與輸入段的存儲器屬性相匹配的存儲器訪問屬性(如果有);
· input_section_pattern。
13.4.3 Scatter文件典型用法
1.創(chuàng)建啟動域
所謂啟動域就是加載地址和執(zhí)行地址相同的域。系統(tǒng)執(zhí)行的初始入口點必須要在啟動域中,否則鏈接器將報告以下錯誤。
Entry point (0x00000000) lies within non-root region ER_ROM
在Scatter文件中確定啟動域可以使用下面兩種方法。
① 使用ABSOLUTE設置執(zhí)行區(qū)屬性,并且對第一個執(zhí)行區(qū)及其所在的加載區(qū)使用相同的地址。為確保執(zhí)行域地址和加載域地址相同,可以將加載域的起始地址和執(zhí)行域的起始地址設為相同的值或者將第一個執(zhí)行域的地址偏移量設為0。
下面的例子,指定了一個啟動域。
BOOT 0x0000 ;加載域的起始地址在0x0
{
EXER 0x0000 ;指定加載域和執(zhí)行域的地址相同
{
* (+RO) ;必須將啟動域包含在內(nèi)
}
;其他執(zhí)行域
}
② 使用FIXED執(zhí)行域?qū)傩?,確保指定域的載入地址和執(zhí)行地址相同。
下面的例子顯示了使用FIXED屬性,將執(zhí)行域的起始地址固定在ROM中。
BOOT 0x0000 ;加載域的起始地址在0x0
{
EXER 0x0000 ;指定加載域和執(zhí)行域的地址相同
{
* (+RO) ;必須將啟動域包含在內(nèi)
}
EXER_INIT 0x8000 FIXED
{
init.o(+RO)
}
}
③ 如果使用分散加載,負責創(chuàng)建執(zhí)行域的代碼和數(shù)據(jù)不能將其自身復制到另一位置,因此啟動域必須包含以下內(nèi)容。
· _main.o和_scatter*.o:包含復制代碼和數(shù)據(jù)的代碼。
· Region$$Table和ZISection$$Table段:包含要復制代碼和數(shù)據(jù)的地址。
· _dc*.o:執(zhí)行代碼壓縮。
可以使用armlinker產(chǎn)生的InRoot$$Sections符號放置啟動代碼。因為這些代碼被定義為只讀屬性,所有如果Scatter文件中包含了“* (+RO)”,則表示啟動域中包含了這些代碼。或者顯式的使用InRoot$$Sections符號在Scatter文件中對以上代碼進行配置。
下面的例子顯示了如何在Scatter文件中使用InRoot$$Sections鏈接符號,放置啟動域。
LOADREG 0x8000 ;
{
ROOT 0x8000
{
* (InRoot$$Sections) ;放置啟動域
}
OTHER 0x100000
{
* (RO,+RW,+ZI)
}
;其他Scatter文件描述
}
存儲器相關(guān)文章:存儲器原理
評論