在MTK机器的固件中,发现与一般Android系统固件有一些不同的地方,比如固件根目录下有一个名为scatter.txt的文件,简单的打开看了下内容,看上去像是系统的分区信息,如果替换成不同机型的scatter.txt文件,刷机时会提示分区信息不匹配,删掉的话,会直接提示ota什么错误,看来是一个很关键的文件。因此我也在网上搜索一下相关资料,有兴趣的同学可以了解一下!
映像(Image)文件有两个视图:加载视图(Load view) 和 执行视图(execution view)。在下载的时候Image regions被放置在memory map当中,而在执行Image前,或许你需要将一些regions放置在它们执行时的地址上,并建立起ZI regions。例如,你初始化的RW数据需要从它在下载时的在ROM中的地址处移动到执行时RAM的地址处。
映像中所有的代码和数据都有一个装载地址和运行地址(二者可能相同也可能不同,视具体情况而定)。在系统启动时,C函数库中的__main初始化代码会执行必要的复制及清零操作,使应用程序的相应代码和数据段从装载状态转入执行状态。
1.jpg(63.03 KB)
(下载次数: 22, 2012-11-9 11:47 上传) 2.jpg(85.97 KB)
(下载次数: 23, 2012-11-9 11:47 上传) 4.jpg(105.79 KB)
(下载次数: 20, 2012-11-9 11:47 上传) 为什么需要Scatter文件:
制定存储器映射(memory map)的方法基本上有二种,一是在link时使用命令行选项,并在程序执行前利用linker pre-define symbol使用汇编语言制定section的段初始化,二是使用scatter file,即采用“分散加载机制”。以上二种方法依应用程序的复杂度而定,一针对简单的情况,二针对复杂的情况。
手机属于复杂的情况,必须使用scatter file。
Scatter文件语法:
scatter文件是一个简单的文本文件,包含一些简单的语法(分号后面的内容是注释):
My_Region 0x0000 0x1000 ;区域名称 区起始地址 区长度
{
the context of region ;区内容
}
每个区由一个头标题开始定义,头中至少包含区的名字和起始地址,另外还有最大长度和其他一些属性选项。区定义的内容包括在紧接的一对花括号内,依赖于具体的系统情况。
一个加载区必须至少含有一个执行段;实践中通常有多个执行段。
一个执行区必须至少含有一个代码或数据段;这些通常来自源文件或库函数等的目标文件;通配符号*可以匹配指定属性项中所有没有在文件中定义的余下部分。
简单分散加载样例
图8所示样例中,只有一个加载区,包含了所有的代码和数据,起始地址为0。这个加载区一共对应两个执行段。一个包含所有的RO代码和数据,执行地址与装载地址相同;同时另一个起始地址为0x10000的执行段,包含所有的RW和ZI数据。这样当系统开始启动时,从第一个执行段开始运行(执行地址等于装载地址),在执行过程中,有一段初始化代码会把装载区中的一部分代码转移到另外的执行段中。
下面是这个scatter描述文件,该文件描述了上述存储器映射方式。
LOAD_ROM 0x4000
{
EXE_ROM 0x0000 0x4000
{
*〈+RO〉 ;所有代码、常量数据
}
RAM 0x10000 0x8000
{
*〈+RW,+ZI〉 ;所有非常量数据
}
}
在分散文件中放置对象
在大多数应用中,并不是像前例那样,简单地把所有属性都放在一起,用户需要控制特定代码和数据段的放置位置。这可以通过在scatter文件中对单个目标文件进行定义实现,而不是只简单地依靠通配符。
为了覆盖标准的连接器布局规则,我们可以使用+FIRST和+LAST分散加载指令。典型的例子是在执行段的开始处放置中断向量表格:
LOAD_ROM 0x0000 0x4000
{
EXEC_ROM 0x0000 0x4000
{
vectors.o〈Vect,+FIRST〉
*〈+RO〉
}
;moreexecregions...
}
在这个scatter文件中,保证了vextors.o中的Vect域被放置于地址0x0000。
一个实际的Scatter.txt详细分析
ROM 0x00 0x800000 ;名字为ROM的区,起始地址是0x00,区的长度是0x800000。区的名字是唯一的;MTK平台对第一个区的大小限制是8Mbytes
{
ROM 0x00 FIXED 0x3D8000 ;名称为ROM的执行段,该名称在所有执行段中是唯一的。段的起始地址是0x00,长度固定为0x3D8000.
{
bootarm.obj (C$$code,+First) ; First指把代码放到本段的起始地址处,C$$code的含义可能是一个块的名字.
*.obj (LEADING_PART,+First) ;含义应该是:把后缀名为.obj的文件的LEADING_PART块放到紧挨前面(即bootarm.obj的结尾处)的地方。
*.l (+RO) ;所有以.l为后缀的文件的可执行代码、常量放置在这里。
*bmt.lib (+RO) ;所有以bmt.lib结尾的文件的可执行代码、常量放置在这里。
*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) ;这行语句被注释了,无效
*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块(可以是代码、数据)放在这里。
; *mmiresource.lib (+RO)
custNFBProgressImg.obj (+RO)
gui_wrapper.obj (+RO)
}
DYNAMIC_CODE2 0xA0018800 OVERLAY 0x2800 ;对照MT6228芯片的地址空间表,DYNAMIC_CODE2块将放在TCM中。
{
* (G3D_DYNAMIC_CODE, G3D_DYNAMIC_ZI) ;块G3D_DYNAMIC_CODE、G3D_DYNAMIC_ZI包含的代码、数据都放这。
}
DYNAMIC_CODE1 0xA001B000 OVERLAY 0x5000
{
* (AMR515_DYNAMIC_CODE, AMR515_DYNAMIC_ZI)
}
DYNAMIC_CODE3 0xA001B000 OVERLAY 0x5000
{
* (CTM_DYNAMIC_CODE, CTM_DYNAMIC_ZI)
}
DYNAMIC_CODE4 0xA001B000 OVERLAY 0x5000
{
* (G729_DYNAMIC_CODE, G729_DYNAMIC_ZI)
}
DYNAMIC_CODE5 0xA001B000 OVERLAY 0x5000
{
* (SBC_DYNAMIC_CODE, SBC_DYNAMIC_ZI)
}
PRIMARY_EXTSRAM 0x400000 FIXED 0x400000 ; 段的名字是PRIMARY_EXTSRAM,起始地址是0x400000,长度固定为0x400000。
{
*.l (+RW)
*bmt.lib (+RW)
*adaptation.lib (+RW) ;所有以adaptation.lib结尾的文件的可读写数据放到这里。
*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) ;代码被注释了,无效
ScreenRotation.obj (+RW)
wingui.obj (+RW)
wgui_categories.obj (+RW)
; *mmiresource.lib (+RW)
custNFBProgressImg.obj (+RW)
gui_wrapper.obj (+RW)
; ZI chunk
* (+ZI) ;其他所有文件中的数据都放这,且开机时会把这些数据清零。
}