简体   繁体   English

如何在 IAR linker 脚本中定义总图像大小或其结束地址的符号?

[英]How to define a symbol for total image size or its end address in IAR linker script?

I'd like to define a symbol in IAR C program to get the total size (or the end address) of the image, in the build time , so that this size or offset will be contained in the image after linking.我想在 IAR C 程序中定义一个符号,以在构建时获取图像的总大小(或结束地址),以便在链接后将此大小或偏移量包含在图像中。

(I know that this can be done in a post-build action. Also, I know how to do this with the gnu linker) (我知道这可以在构建后操作中完成。另外,我知道如何使用 gnu 链接器执行此操作)

The IAR documentation on expressions in the link scripts says about functions 'size' and 'end'.有关链接脚本中表达式的 IAR 文档说明了函数“大小”和“结束”。 The problem is that I don't know the section or segment names.问题是我不知道节或段名称。

From the map file, the linker creates sections named P1, P2, A1, and so on.从 map 文件中,linker 创建了名为 P1、P2、A1 等的部分。 The read-only code + data + init data section is likely what I want, it is named "P1".只读代码+数据+初始化数据部分很可能是我想要的,它被命名为“P1”。

Snippet from the map file:来自 map 文件的片段:

*******************************************************************************
*** PLACEMENT SUMMARY
***

"A0":  place at address 0x800'8000 { ro section .intvec };
"P1":  place in [from 0x800'8000 to 0x807'ffff] { ro };
.......... etc.......

I tried: define exported symbol MY_SIZE = size("P1");我试过: define exported symbol MY_SIZE = size("P1"); or define exported symbol MY_SIZE = size(P1);define exported symbol MY_SIZE = size(P1); but get error message "Error[Lc007]: expected an identifier".但收到错误消息“错误[Lc007]:需要一个标识符”。 "Error[Lc010]: "P1" is not a region name". “错误 [Lc010]:“P1”不是区域名称”。

What is the correct argument for size and end functions? size 和 end 函数的正确参数是什么? Or any other way to do this?或任何其他方式来做到这一点?

Yes.是的。 The current IAR linker comes with the start() , end() and size() functionalities.当前的 IAR linker 带有start()end()size()功能。 However, as for now, those only apply to regions.但是,就目前而言,这些仅适用于地区。

define exported symbol _start_address = start(ROM_region);
define exported symbol _end_address = end(ROM_region);

However, in the linker configuration, regions are bound to literals.但是,在 linker 配置中,区域绑定到文字。 So, here the "_start_address" will refer to the initial address of the ROM_region and "_end_address" will be the ending address, which is independent from the program size.所以,这里的“_start_address”指的是ROM_region的起始地址,“_end_address”指的是结束地址,与程序大小无关。

An alternative approach for getting where the user program itself starts/ends can be to place 2 rooted dummy sections as wrappers around the sections actually being placed in the ROM_region:获取用户程序本身开始/结束位置的另一种方法是放置 2 个根虚拟部分作为实际放置在 ROM_region 中的部分的包装器:

define root section _start_section with alignment = 4 { public _ss: udata32 0xA5A5A5A5; };
define root section _end_section with alignment = 4 { public _es: udata32 0xBABABABA; };

"ROM": place in ROM_region { first section _start_section,
                             ro,
                             last section _end_section };  

From the C program (/debugger) these addresses can be accessed directly via "extern":从 C 程序 (/debugger) 可以通过“extern”直接访问这些地址:

#include <stdio.h>
void main() {
  extern const void * _ss;
  extern const void * _es;
  printf("Initial 32-bit address: 0x%08x\n", &_ss);
  printf("Final 32-bit address: 0x%08x\n", &_es);
}
/* Output example (Terminal I/O) */
// Initial 32-bit address: 0x08000000
// Final 32-bit address: 0x08000B68

If your program's "ROM_region" has complex partitioning, the same concept would still be potentially usable as far as the "start section" and "end section" are placed in a fixed order block which lumps all the sections/blocks other than "ro":如果您的程序的“ROM_region”具有复杂的分区,只要“开始部分”和“结束部分”被放置在一个固定顺序的块中,该块将除“ro”之外的所有部分/块集中在一起,相同的概念仍然可能可用:

define block RO_BLOCK with fixed order, end alignment = 4 {
                                         section _start_section,
                                         ro,
                                         /* sections/blocks other than "ro" */
                                         section _end_section };
                                         
"ROM": place in ROM_region { block RO_BLOCK };                                  

Either way, the addresses are defined within the ELF at linking time, without the need for an external utility to patch it during a post-build step.无论哪种方式,地址都是在链接时在 ELF 中定义的,不需要外部实用程序在构建后步骤中对其进行修补。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM