在调试某芯片平台时,希望将flash上的一片地方采用绝对地址定位定一个数组。于是修改了链接文件,当时的链接文件如下:
MEMORY
{
rom : ORIGIN = 0x00000000, LENGTH = 64k
ram : ORIGIN = 0x00800800, LENGTH = 4k
eflash : ORIGIN = 0x00400000, LENGTH = 24k
JTEST : ORIGIN = 0x00408000, LENGTH = 100k
}
SECTIONS
{
.text_entry : {
VECTOR_LOCATION = .;
KEEP(vector_table.o(.rodata));
} >eflash
.rodata : {
( .rodata);
} >eflash
.text : {
*( .text*);
. = ALIGN(16);
_end_text = .;
} >eflash = 0xbebe
.gJTEST 0x408000: {
KEEP(*test.o(.text*));
KEEP(*( .gJTEST));
} >JTEST
.data : AT(_end_text)
{ _start_data = .;
*( .data );
. = ALIGN(4);
_end_data = .;
} >ram
.bss : { _bss_start = .;
*( .bss ) *(COMMON);
. = . + 0x08;
_bss_end = .;
} >ram
}
test.c文件如下:
attribute ((section (".gJTEST ")))
void AAAtest(void)
{
int i;
for(i=0; i<100;i++)
Buff[i] = 0xaa;
}
编译完以后,看map文件发现已经将函数 AAAtest 定位到了0x408000这个地址,在主函数中调用 AAAtest 的时候,采用函数指针指向绝对地址,然后调用的方式,发现每次调用总会引起芯片异常复位。查看编译出来的hex文件发现 0x408000 这个地址上面没有数据。这种情况是map中显示已经将文件进行了绝对地址定位,但是hex文件中并没有相应的数据。后来修改链接文件如下:
MEMORY
{
rom : ORIGIN = 0x00000000, LENGTH = 64k
ram : ORIGIN = 0x00800800, LENGTH = 4k
eflash : ORIGIN = 0x00400000, LENGTH = 24k
JTEST : ORIGIN = 0x00408000, LENGTH = 100k
}
SECTIONS
{
.text_entry : {
VECTOR_LOCATION = .;
KEEP(vector_table.o(.rodata));
} >eflash
.rodata : {
( .rodata);
} >eflash
.gJTEST 0x408000: {
KEEP(*test.o(.text*));
KEEP(*( .gJTEST));
} >JTEST
.text : {
*( .text*);
. = ALIGN(16);
_end_text = .;
} >eflash = 0xbebe
.gJTEST 0x408000: {
KEEP(*test.o(.text*));
KEEP(*( .gJTEST));
} >JTEST
.data : AT(_end_text)
{ _start_data = .;
*( .data );
. = ALIGN(4);
_end_data = .;
} >ram
.bss : { _bss_start = .;
*( .bss ) *(COMMON);
. = . + 0x08;
_bss_end = .;
} >ram
}
编译链接发现hex文件中已经显示 地址 0x408000 上有数据了,再次调用测试函数没有问题。
问题的原因是在.text这个段中要将所有的代码段链接到那儿去,如果将需要特殊处理的段 .gJTEST 放在 .text 段后面,在 .text 段中已经将所有的东西放在了那儿,后面再有 .gJTEST 的时候 链接器发现已经链接了测试函数,就不再对测试函数进行链接了,解决这个问题只能将需要特殊处理的段放在 .text 之前。