MTK平臺(tái)中關(guān)于Scatter文件學(xué)習(xí)教程
MTK平臺(tái)中關(guān)于Scatter文件學(xué)習(xí)是本文要介紹的內(nèi)容,主要是來了解MTK平臺(tái)中Scatter文件的應(yīng)用,具體內(nèi)容來看本文詳解。
分散加載(scatterloading)是ARM連接接器提供的一個(gè)機(jī)制,該機(jī)制可以把一個(gè)可執(zhí)行映像文件(即Bin文件)分割放置到內(nèi)存中不同的獨(dú)立段。
映像(Image)文件有兩個(gè)視圖:加載視圖(Loadview)和執(zhí)行視圖(executionview)。在下載的時(shí)候Imageregions被放置在memorymap當(dāng)中,而在執(zhí)行Image前,或許你需要將一些regions放置在它們執(zhí)行時(shí)的地址上,并建立起ZIregions。例如,你初始化的RW數(shù)據(jù)需要從它在下載時(shí)的在ROM中的地址處移動(dòng)到執(zhí)行時(shí)RAM的地址處。
在scatter文件中可以為每一個(gè)代碼或數(shù)據(jù)段在裝載和執(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í)行區(qū)。
映像中所有的代碼和數(shù)據(jù)都有一個(gè)裝載地址和運(yùn)行地址(二者可能相同也可能不同,視具體情況而定)。在系統(tǒng)啟動(dòng)時(shí),C函數(shù)庫(kù)中的__main初始化代碼會(huì)執(zhí)行必要的復(fù)制及清零操作,使應(yīng)用程序的相應(yīng)代碼和數(shù)據(jù)段從裝載狀態(tài)轉(zhuǎn)入執(zhí)行狀態(tài)。



為什么需要Scatter文件:
制定存儲(chǔ)器映射(memorymap)的方法基本上有二種,一是在link時(shí)使用命令行選項(xiàng),并在程序執(zhí)行前利用linkerpre-definesymbol使用匯編語(yǔ)言制定section的段初始化,二是使用scatterfile,即采用“分散加載機(jī)制”。以上二種方法依應(yīng)用程序的復(fù)雜度而定,一針對(duì)簡(jiǎn)單的情況,二針對(duì)復(fù)雜的情況。
手機(jī)屬于復(fù)雜的情況,必須使用scatterfile。
Scatter文件語(yǔ)法:
scatter文件是一個(gè)簡(jiǎn)單的文本文件,包含一些簡(jiǎn)單的語(yǔ)法(分號(hào)后面的內(nèi)容是注釋):
My_Region0x00000x1000;區(qū)域名稱區(qū)起始地址區(qū)長(zhǎng)度
- {
- thecontextofregion;區(qū)內(nèi)容
- }
每個(gè)區(qū)由一個(gè)頭標(biāo)題開始定義,頭中至少包含區(qū)的名字和起始地址,另外還有最大長(zhǎng)度和其他一些屬性選項(xiàng)。區(qū)定義的內(nèi)容包括在緊接的一對(duì)花括號(hào)內(nèi),依賴于具體的系統(tǒng)情況。
一個(gè)加載區(qū)必須至少含有一個(gè)執(zhí)行段;實(shí)踐中通常有多個(gè)執(zhí)行段。
一個(gè)執(zhí)行區(qū)必須至少含有一個(gè)代碼或數(shù)據(jù)段;這些通常來自源文件或庫(kù)函數(shù)等的目標(biāo)文件;通配符號(hào)*可以匹配指定屬性項(xiàng)中所有沒有在文件中定義的余下部分。
簡(jiǎn)單分散加載樣例
圖8所示樣例中,只有一個(gè)加載區(qū),包含了所有的代碼和數(shù)據(jù),起始地址為0。這個(gè)加載區(qū)一共對(duì)應(yīng)兩個(gè)執(zhí)行段。一個(gè)包含所有的RO代碼和數(shù)據(jù),執(zhí)行地址與裝載地址相同;同時(shí)另一個(gè)起始地址為0x10000的執(zhí)行段,包含所有的RW和ZI數(shù)據(jù)。這樣當(dāng)系統(tǒng)開始啟動(dòng)時(shí),從第一個(gè)執(zhí)行段開始運(yùn)行(執(zhí)行地址等于裝載地址),在執(zhí)行過程中,有一段初始化代碼會(huì)把裝載區(qū)中的一部分代碼轉(zhuǎn)移到另外的執(zhí)行段中。
下面是這個(gè)scatter描述文件,該文件描述了上述存儲(chǔ)器映射方式。
- LOAD_ROM0x4000
- {
- EXE_ROM0x00000x4000
- {
- *〈+RO〉;所有代碼、常量數(shù)據(jù)
- }
- RAM0x100000x8000
- {
- *〈+RW,+ZI〉;所有非常量數(shù)據(jù)
- }
- }
在分散文件中放置對(duì)象
在大多數(shù)應(yīng)用中,并不是像前例那樣,簡(jiǎn)單地把所有屬性都放在一起,用戶需要控制特定代碼和數(shù)據(jù)段的放置位置。這可以通過在scatter文件中對(duì)單個(gè)目標(biāo)文件進(jìn)行定義實(shí)現(xiàn),而不是只簡(jiǎn)單地依靠通配符。
為了覆蓋標(biāo)準(zhǔn)的連接器布局規(guī)則,我們可以使用+FIRST和+LAST分散加載指令。典型的例子是在執(zhí)行段的開始處放置中斷向量表格:
- LOAD_ROM0x00000x4000
- {
- EXEC_ROM0x00000x4000
- {
- vectors.o〈Vect,+FIRST〉
- *〈+RO〉
- }
- ;moreexecregions...
- }
在這個(gè)scatter文件中,保證了vextors.o中的Vect域被放置于地址0x0000。
一個(gè)實(shí)際的Scatter.txt詳細(xì)分析
ROM0x000x800000;名字為ROM的區(qū),起始地址是0x00,區(qū)的長(zhǎng)度是0x800000。區(qū)的名字是唯一的;MTK平臺(tái)對(duì)第一個(gè)區(qū)的大小限制是8Mbytes
{
ROM0x00FIXED0x3D8000;名稱為ROM的執(zhí)行段,該名稱在所有執(zhí)行段中是唯一的。段的起始地址是0x00,長(zhǎng)度固定為0x3D8000.
{
bootarm.obj(C$$code,+First);First指把代碼放到本段的起始地址處,C$$code的含義可能是一個(gè)塊的名字.
*.obj(LEADING_PART,+First);含義應(yīng)該是:把后綴名為.obj的文件的LEADING_PART塊放到緊挨前面(即bootarm.obj的結(jié)尾處)的地方。
*.l(+RO);所有以.l為后綴的文件的可執(zhí)行代碼、常量放置在這里。
*bmt.lib(+RO);所有以bmt.lib結(jié)尾的文件的可執(zhí)行代碼、常量放置在這里。
- *adaptation.lib(+RO)
- *config.lib(+RO)
- *custom.lib(+RO)
- *drv.lib(+RO)
- *fdm.lib(+RO)
- *init.lib(+RO)
- *kal.lib(+RO)
- *l1_classb.lib(+RO)
- *nucleus.lib(+RO)
- *nucleus_int.lib(+RO)
- *nucleus_debug.lib(+RO)
- *stacklib.lib(+RO)
- *sst.lib(+RO)
- *tst.lib(+RO)
- *mtkapp.lib(+RO)
- *usb.lib(+RO)
- ;*j2me_hi.lib(+RO);這行語(yǔ)句被注釋了,無(wú)效
- *nvram.lib(+RO)
- *nvram_sec.lib(+RO)
- *ft.lib(+RO)
- *irda.lib(+RO)
- *fs.lib(+RO)
- *media.lib(+RO)
- *media_sec.lib(+RO)
- *dsp_ram.lib(+RO)
- ;*plutommi.lib(+RO)
- ScreenRotation.obj(+RO)
- wingui.obj(+RO)
- wgui_categories.obj(+RO)
- ;*media.lib(+RO)
- png_decoder_sw.obj(PRIMARY_CODE);png_decoder_sw.obj文件中的PRIMARY_CODE塊(可以是代碼、數(shù)據(jù))放在這里。
- ;*mmiresource.lib(+RO)
- custNFBProgressImg.obj(+RO)
- gui_wrapper.obj(+RO)
- }
- DYNAMIC_CODE20xA0018800OVERLAY0x2800;對(duì)照MT6228芯片的地址空間表,DYNAMIC_CODE2塊將放在TCM中。
- {
- *(G3D_DYNAMIC_CODE,G3D_DYNAMIC_ZI);塊G3D_DYNAMIC_CODE、G3D_DYNAMIC_ZI包含的代碼、數(shù)據(jù)都放這。
- }
- DYNAMIC_CODE10xA001B000OVERLAY0x5000
- {
- *(AMR515_DYNAMIC_CODE,AMR515_DYNAMIC_ZI)
- }
- DYNAMIC_CODE30xA001B000OVERLAY0x5000
- {
- *(CTM_DYNAMIC_CODE,CTM_DYNAMIC_ZI)
- }
- DYNAMIC_CODE40xA001B000OVERLAY0x5000
- {
- *(G729_DYNAMIC_CODE,G729_DYNAMIC_ZI)
- }
- DYNAMIC_CODE50xA001B000OVERLAY0x5000
- {
- *(SBC_DYNAMIC_CODE,SBC_DYNAMIC_ZI)
- }
- PRIMARY_EXTSRAM0x400000FIXED0x400000;段的名字是PRIMARY_EXTSRAM,起始地址是0x400000,長(zhǎng)度固定為0x400000。
- {
- *.l(+RW)
- *bmt.lib(+RW)
- *adaptation.lib(+RW);所有以adaptation.lib結(jié)尾的文件的可讀寫數(shù)據(jù)放到這里。
- *config.lib(+RW)
- *custom.lib(+RW)
- *drv.lib(+RW)
- *fdm.lib(+RW)
- *init.lib(+RW)
- *kal.lib(+RW)
- *l1_classb.lib(+RW)
- *nucleus.lib(+RW)
- *nucleus_int.lib(+RW)
- *nucleus_debug.lib(+RW)
- *stacklib.lib(+RW)
- *sst.lib(+RW)
- *tst.lib(+RW)
- *mtkapp.lib(+RW)
- *usb.lib(+RW)
- *j2me_hi.lib(+RW)
- *nvram.lib(+RW)
- *nvram_sec.lib(+RW)
- *ft.lib(+RW)
- *irda.lib(+RW)
- *fs.lib(+RW)
- *media.lib(+RW)
- *media_sec.lib(+RW)
- *dsp_ram.lib(+RW)
- ;*plutommi.lib(+RW);代碼被注釋了,無(wú)效
- ScreenRotation.obj(+RW)
- wingui.obj(+RW)
- wgui_categories.obj(+RW)
- ;*mmiresource.lib(+RW)
- custNFBProgressImg.obj(+RW)
- gui_wrapper.obj(+RW)
- ;ZIchunk
- *(+ZI);其他所有文件中的數(shù)據(jù)都放這,且開機(jī)時(shí)會(huì)把這些數(shù)據(jù)清零。
- }
小結(jié):MTK平臺(tái)中關(guān)于Scatter文件學(xué)習(xí)教程的內(nèi)容介紹完了,希望通過MTK平臺(tái)Scatter文件的應(yīng)用內(nèi)容的學(xué)習(xí)能對(duì)你有所幫助!