ARC学习(6)arc 编译器overlap 地址重叠方式使用
ARC学习(6)arc 编译器overlap 地址重叠方式使用
armclang/armcc overlay使用方法详见ARM学习(31)编译器对overlay方式的支持。
1、arc overlap 地址重叠方式使用
正常情况下面,链接脚本里面编写了两段section,如果两段section 地址一致,那么会出现如下链接错误
MEMORY
{ROM : ORIGIN = 0x00000000,LENGTH=64KOVERLAY : ORIGIN = 0x10000000,LENGTH=64KRAM : ORIGIN = 0x20000000,LENGTH=64KBANK0 : ORIGIN = 0x3000000,LENGTH=64KBANK1 : ORIGIN = 0x30010000,LENGTH= 64KBANK2 : ORIGIN = 0x30020000,LENGTH=64K
}SECTIONS
{GROUP ADDR(0x10000000)SIZE(64K):{.overlay_func0 ALIGN(4)BLOCK(4):{KEEP("(*.o)")}}>OVERLAY AT>BANKOGROUP ADDR(0x10000000)SIZE(64K):{.overlay_fun1 ALIGN(4) BLOCK(4): {KEEP("(*.o)")}}>OVERLAY AT>BANK1GROUP ADDR(0x10000000)SIZE(64K):{.overlay_fun2 ALIGN(4) BLOCK(4): {KEEP("(*.o)")}}>OVERLAY AT>BANK2
}
如果要进行内存复用,那么必须要把两段code放到同一个section,如果链接器不支持,那么就必定会出现上述的错误,所以在搜索arc的相关手册后,找到-zallow_memory_overlap,测试发现增加该链接选项后,地址即使重叠也不会报上述的重叠错误。
2、arc overlay示例
int test_count_g = 0;
__attribute__ ((section(".overlay fun0"))) int overlay_func1()
{test_count_g++;return test_count_g;
}__attribute__ ((section(".overlay fun1"))) int overlay_func1()
{test_count_g+=2;return test_count_g;
}__attribute__ ((section(".overlay fun2"))) int overlay_func1()
{test_count_g+=3;return test_count_g;
}
MEMORY
{ROM : ORIGIN = 0x00000000,LENGTH=64KOVERLAY : ORIGIN = 0x10000000,LENGTH=64KRAM : ORIGIN = 0x20000000,LENGTH=64KBANK0 : ORIGIN = 0x3000000,LENGTH=64KBANK1 : ORIGIN = 0x30010000,LENGTH= 64KBANK2 : ORIGIN = 0x30020000,LENGTH=64K
}SECTIONS
{GROUP ADDR(0x10000000)SIZE(64K):{.overlay_func0 ALIGN(4)BLOCK(4):{KEEP("(*.o)")}}>OVERLAY AT>BANKOGROUP ADDR(0x10000000)SIZE(64K):{.overlay_fun1 ALIGN(4) BLOCK(4): {KEEP("(*.o)")}}>OVERLAY AT>BANK1GROUP ADDR(0x10000000)SIZE(64K):{.overlay_fun2 ALIGN(4) BLOCK(4): {KEEP("(*.o)")}}>OVERLAY AT>BANK2
}
-
由于是需要多个代码放在统一位置,所以执行地址是一致的,但是加载地址由于是多份,所以必须要放到不同的位置,所以需要通过分散加载才可以完成。
-
因为多份地址,所以初始化的时候,执行地址的代码是空的,根据需要加载对应的代码。
-
三份代码的符号对应同一个地址。
通过elf解析工具以及trace32 都可以确认,三个符号地址相同。
- 如果需要加载overlay_func0,则加载对应的bin文件。
- 如果需要加载overlay_func1,则加载对应的bin文件。
- 如果需要加载overlay_func2,则加载对应的bin文件。
map 文件如下
链接脚本实例:
有加载地址,利用分散加载原理,生成相关bin文件。
MEMORY
{ROM : ORIGIN = 0x00000000,LENGTH=64KOVERLAY : ORIGIN = 0x10000000,LENGTH=64KRAM : ORIGIN = 0x20000000,LENGTH=64KBANK0 : ORIGIN = 0x3000000,LENGTH=64KBANK1 : ORIGIN = 0x30010000,LENGTH= 64KBANK2 : ORIGIN = 0x30020000,LENGTH=64K
}SECTIONS
{GROUP ADDR(0x00000000) SIZE(64K) : {text ALIGN(4)BLOCK(4):{KEEP("(*.o)")}.rodata ALIGN(4)BLOCK(4):{KEEP("(*.o)")}.vectors ALIGN(4)BLOCK(4):{KEEP("(*.o)")}}>ROMGROUP ADDR(0x10000000)SIZE(64K):{.overlay_func0 ALIGN(4)BLOCK(4):{KEEP("(*.o)")}}>OVERLAY AT>BANKOGROUP ADDR(0x10000000)SIZE(64K):{.overlay_fun1 ALIGN(4) BLOCK(4): {KEEP("(*.o)")}}>OVERLAY AT>BANK1GROUP ADDR(0x10000000)SIZE(64K):{.overlay_fun2 ALIGN(4) BLOCK(4): {KEEP("(*.o)")}}>OVERLAY AT>BANK2GROUP ADDR(0x20000000)SIZE(64K):{.overlay_fun2 ALIGN(4) BLOCK(4): {KEEP("(*.o)")}}>OVERLAY AT>BANK2
}
有AT 重定向之后,虚拟地址0x10000000,物理地址 0x30000000,也就是加载地址。
只有执行地址,没有加载地址
MEMORY
{ROM : ORIGIN = 0x00000000,LENGTH=64KOVERLAY : ORIGIN = 0x10000000,LENGTH=64KRAM : ORIGIN = 0x20000000,LENGTH=64KBANK0 : ORIGIN = 0x3000000,LENGTH=64KBANK1 : ORIGIN = 0x30010000,LENGTH= 64KBANK2 : ORIGIN = 0x30020000,LENGTH=64K
}SECTIONS
{GROUP ADDR(0x00000000) SIZE(64K) : {text ALIGN(4)BLOCK(4):{KEEP("(*.o)")}.rodata ALIGN(4)BLOCK(4):{KEEP("(*.o)")}.vectors ALIGN(4)BLOCK(4):{KEEP("(*.o)")}}>ROMGROUP ADDR(0x10000000)SIZE(64K):{.overlay_func0 ALIGN(4)BLOCK(4):{KEEP("(*.o)")}}>OVERLAY GROUP ADDR(0x10000000)SIZE(64K):{.overlay_fun1 ALIGN(4) BLOCK(4): {KEEP("(*.o)")}}>OVERLAY GROUP ADDR(0x10000000)SIZE(64K):{.overlay_fun2 ALIGN(4) BLOCK(4): {KEEP("(*.o)")}}>OVERLAY }
没有重定向,则虚拟地址和物理地址一样,均是最后的可执行地址。
对于section来说,因为是执行视图,所以两者都一致,bin的位置也一样,可以解析出想关的bin数据,然后加载。