第二章 scatter語法(一)基本結構
先來看一下,一個scatter文件的整體結構,如下圖:
接下來分別對其進行詳細說明。
2.1 加載region的描述信息
加載region的描述信息指出了它的孩子——執行region——的放置情況
2.1.1 加載region的描述信息組成元素
加載region描述信息由下面組成:
- 名字——被鏈接器用於標記唯一的加載region
- 基址——在這個region下的數據和代碼開始的地址
- 屬性
- 可選的最大長度
- 一個或多個執行regoin
如下圖
2.1.2 加載region的屬性
ABSOLUTE:
鏈接之後,內容被放置在一個固定地址。除非你使用PI或者RELOC屬性,否則這個屬性是默認值
ALIGN aligment:
將4字節對齊,增加到aligment字節對齊。aligment必須是2的正數冪。如果加載region直接指定基址,那麼基址必須對齊;如果加載region使用+offset的方式指定基址,那麼鏈接器自動計算以保證對齊。
NOCOMPRESS:
默認情況下RW數據被壓縮,該屬性使得RW數據內容不被壓縮。
OVERLAY:
該屬性使得在同一個地址,具有多個加載region。ARM工具集不會提供overlay機制。爲了在同一個位置放置多個加載region,你必須提供自己的overlay管理器。
PI:
標記該region是地址無關的。內容不會依賴於任何固定的地址。
PROTECTED:
該屬性阻止:
- 加載region的重疊
- venner的共享
- 使用–merge選項共享字符串
注意:venner,指的是鏈接器生成的一小段代碼,這段代碼可能用於長距離的跳轉等。
RELOC:
標記該region是可重定位的。重定位信息會被保存,使其能夠被其他的工具移動到其他位置,已達到可重定位的功效
2.1.3 加載region的地址屬性繼承規則
加載region可以繼承上一個加載region的屬性。爲了達到此目的,只需要使用+offset的方式設置基址即可。如下情況下無法繼承屬性:
- 顯示的設置了加載region的屬性
- 前一個加載region具有OVERLAY屬性
你可以顯式的使用ABSOLUTE,PI,RELOC,OVERLAY指定地址屬性,當地址屬性沒有被指定時,下面的繼承規則將會被應用:
- OVERLAY屬性不會被繼承
- 加載和執行region的基址默認爲ABSOLUTE
- +offset會繼承上一個region的地址屬性,如果沒有上一個region,則爲ABSOLUTE屬性。
例如:
LR1 0x8000 PI
{
…
}
LR2 +0 ; LR2從LR1繼承PI屬性
{
…
}
LR3 0x1000 ; LR3不會繼承因爲它沒有相對基址,所以爲默認屬性ABSOLUTE
{
…
}
LR4 +0 ; LR4從LR3繼承ABSOLUTE
{
…
}
LR5 +0 RELOC ; LR5不會繼承,因爲它顯式設置了RELOC
{
…
}
LR6 +0 OVERLAY ; LR6不會繼承,因爲有OVERLAY
{
…
}
LR7 +0 ; LR7不會繼承OVERLAY,因此是默認屬性ABSOLUTE
{
…
}
2.1.4 RELOC地址屬性的繼承規則
你可以給加載region設置一個RELOC屬性。但是,執行region僅可以從父加載region中繼承RELOC。
注意:對於BP鏈接模型,如果加載region有RELOC屬性,那麼所有的在這個加載region內的執行region必須是+offset方式來指定基址。這個保證了執行region繼承父加載region的重定位信息。
例如:
LR1 0x8000 RELOC
{
ER1 +0 ; 從LR1中繼承RELOC屬性
{
…
}
ER2 +0 ; 從ER1中繼承RELOC屬性
{
…
}
ER3 +0 RELOC ; 錯誤,不能在執行region中顯式指定RELOC屬性
{
…
}
}
2.2 執行region的描述信息
這部分指定了region在運行時處在內存的什麼位置。
2.2.1 執行region的描述信息組成元素
由下面的元素組成:
- 名字——被鏈接器標識,用於區分不同的執行region
- 基址——不是絕對值就是相對值
- 屬性
- 可選的最大長度
- 一個或多個輸入section的模式字符串
如下圖:
2.2.2 執行region的屬性
ABSOLUTE:
鏈接之後,內容被放置於一個固定的地址。
ALIGN aligment:
將4字節對齊提升到aligment字節對齊。aligment必須是2的正數冪。如果執行region被設置了基址,那麼他必須按照aligment字節對齊。如果執行region被設置了偏移,那麼鏈接器自動計算地址,以達到aligment字節對齊。
ALIGNALL value:
增加執行region中各section的對齊爲value字節對齊。value的值必須是2的正數冪,並且必須大於等於4
ANY_SIZE max_size:
指定,該region可以放置的未分配section(即.ANY匹配的section)的最大大小。
例如:如果一個執行region,將僅被.ANY匹配的section填充,那麼2%將用於venner。剩下的98%纔會用於.ANY匹配的section
使用這個關鍵字時,注意下面的限制:
- max_size 必須小於或者等於region大小
- 可以在沒有.ANY選擇器的region上使用ANY_SIZE.但是,他會被armlink忽略。
EMPYT [-]length:
在內存中保留一個給定大小的空的區域。通常被用作堆或棧區域。在帶有EMPTY屬性的region中,不能放置任何section。
length爲正數,則基址爲起始地址。length爲負數,則基址爲結束地址。
FILL value:
鏈接器創建一個region,該region填充value。如果你指定了FILL,那麼就必須跟一個value。例如FILL 0xFFFFFFFF.他相當於EMPTY ZEROPAD PADVALUE
FIXED:
固定地址,鏈接器嘗試使執行地址和加載地址相同。如果無法相同將報錯。
NOCOMPRESS:
armlink默認是打開RW數據壓縮的。該屬性使得RW數據不被壓縮。
OVERLAY:
指示該region可能會有重疊的section。
PADVALUE:
定義填充的值。PADVALUE必須跟一個值,例如:
EXEC 0x10000 PADVALUE 0xffffffff EMPTY ZEROPAD 0x2000
這將創建一個大小0x2000,填滿0xffffffff的region
PADVALUE屬性的值必須是字大小,且被加載region所忽略。
PI:
該region僅包含位置無關的section。
注意:該屬性在包含XO section時,不支持
SORTTYPE:
指定執行region的排序算法,例如:
ER1 +0 SORTTYPE CallTree
UNINIT:
用於創建包含未初始化數據或者內存映射IO的region。
ZEROPAD:
零初始化的section被寫入ELF中,因此不用在運行時填充零
該屬性設置ZI輸出section的長度,並保存在Image$$region_name$$ZI$$Length中。
注意:Image$$region_name$$ZI$$Length是鏈接器使用的一些符號。因爲本系列文章的主旨是scatter文件。因此不再對鏈接器的符號做進一步說明。
只有root region可以使用這個屬性。否則將產生一個警告,並忽略。
2.2.3 執行region的地址屬性的繼承規則
執行region可以繼承上一個執行region的屬性。
爲了繼承,直接使用+offset的形式來指定基址。第一個執行region繼承其父加載region的屬性。
執行region在下面情況下無法繼承屬性:
- 顯式設置了執行region的屬性
- 上一個執行region具有OVERLAY屬性
你可以使用ABSOLUTE,PI,OVERLAY屬性,顯式的設置執行region。但是,執行region僅繼承父加載region的RELOC屬性。
當沒有地址屬性被設置時,下面的繼承規則會發生:
- OVERLAY屬性不會被繼承,含有OVERLAY屬性的region也不會繼承
- 加載或者執行region的基址默認是ABSOLUTE
- 通過+offset設置的地址,將會繼承上一個執行region的地址屬性,如果沒有上一個,則繼承父加載region的地址屬性
例如:
LR1 0x8000 PI
{
ER1 +0 ; ERI從LR1中繼承PI
{
…
}
ER2 +0 ; ER2從ER1中繼承PI
{
…
}
ER3 0x10000 ; ER3沒有繼承,因爲他沒有使用相對基址,因此它使用了默認屬性ABSOLUTE
{
…
}
ER4 +0 ; ER4從ER3中繼承ABSOLUTE
{
…
}
ER5 +0 PI ; ER5不會繼承,因爲他顯式設置了PI
{
…
}
ER6 +0 OVERLAY ; ER6不會繼承,因爲他設置了OVERLAY
{
…
}
ER7 +0 ; ER7不會繼承OVERLAY,因此使用默認屬性ABSOLUTE
{
…
}
}
2.2.4 相對地址用在加載region上的情況
當相對地址用在加載region上時,需要注意如下情況:
- 如果使用+offset的加載region(LR2)跟在一個含有ZI數據的加載region(LR1)之後。那麼LR2將覆蓋ZI數據。爲了修復這個,使用ImageLimit()函數來指定LR2的基址。
注意:這在下一章中有例子
- LR2繼承LR1的屬性,除非如下情況:
- LR1有OVERLAY屬性
- LR2顯式設置了屬性
如果一個加載region無法繼承屬性,那麼它將使用默認值ABSOLUTE。
- 在ROM鏡像中,如果一個region含有RW數據壓縮,且下一個region使用+offset設置基址,則在這兩個region之間,可能存在一個空隙。這是因爲鏈接器計算相對基址時,是相對於未壓縮數據的。但是這個空隙會在運行時消失。因爲運行時會解壓出來。
2.2.5 相對地址用在執行region上的情況
當相對地址用在執行region上時,需要注意一下情況:
- 除非執行region被顯式的設置屬性,否則,第一個執行region繼承父加載region的屬性。
- 使用相對地址的執行region(ER2)繼承執行region(ER1)的屬性,除非如下情況:
- ER1有OVERLAY屬性
- ER2有一個顯式的屬性設置
如果一個執行region無法繼承屬性,那麼將使用默認值ABSOLUTE
- 如果父加載region有RELOC屬性,那麼在其內的所有的執行region必須使用相對地址。
2.3 輸入section的描述信息
輸入section的描述信息是一個模式字符串,用於選擇section
2.3.1 輸入section的描述信息組成元素
由如下部分組成:
- 名字,可以使用通配符——中間文件名,庫成員名,或者庫名字
- 輸入sectoin名,或者輸入section屬性,例如READ-ONLY,或者CODE。輸入section名也可以使用通配符
- 符號名
如下圖:
2.3.2 模塊和輸入section模式字符串舉例
模塊匹配舉例:
- * 匹配任何模塊和庫
- *.o 匹配任何以o結尾的模塊
- math.o 匹配math.o 模塊
- *armlib* 匹配所有ARM支持的C庫
- “file1.o” 匹配file1.o
- *math.lib 匹配所有以math.lib結尾的庫。例如:c:\apps\lib\math\satmath.lib
輸入section匹配舉例:
- +RO 匹配所有RO代碼和RO數據
- +RW,+ZI 匹配所有的RW代碼,所有的RW數據,所有ZI數據
- BLOCK_42 匹配名字叫做BLOCK_42的section。這個名字可能有多個section,但是他們的屬性可能不同。
本章完,下章scatter文件中使用的表達式和函數