IAR 链接器配置文件 - 缺少“.intvec”放置

IAR Linker Configuration File - Missing ".intvec" Placement

我正在处理一个 IAR 项目,其中有用于引导加载程序和主应用程序的 ILINK 配置文件 (.icf)。每个文件都定义了 __ICFEDIT_intvec_start__ 符号,然后将其放置在引用各自 .intvec 部分的位置(有 2 个 cstartup.s 文件,每个文件都有自己的 .intvec 部分):


引导加载程序.icf:

    define symbol __ICFEDIT_intvec_start__ = 0x18000000;
    ...
    place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

申请.icf

    define symbol __ICFEDIT_intvec_start__ = 0x18080000;
    ...
    place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

据我了解,这些 .icf 文件中的每一个都用于生成它们自己的 .map 文件。看到这些中的每一个如何引用两个不同的部分(共享相同的名称),我很困惑为什么只有引导加载程序的 .map 文件引用 .intvec 部分:


引导程序.map:

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

    "A1":  place at 0x18000000 { ro section .intvec };
    "P1":  place in [from 0x18000040 to 0x1807ffff] { ro };
    "P2":  place in [from 0x20020000 to 0x209fffff] {
              rw, block CSTACK, block SVC_STACK, block IRQ_STACK, block FIQ_STACK,
              block UND_STACK, block ABT_STACK, block HEAP };

      Section            Kind        Address    Size  Object
      -------            ----        -------    ----  ------
    "A1":                                       0x3c
      .intvec            ro code  0x18000000    0x3c  cstartup.o [1]
                                - 0x1800003c    0x3c
    ...

申请.map

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

    "INT_VEC_RAM":
           place at 0x20020000 { section .intvec_RAM };
    "ROM": place in [from 0x18080040 to 0x1bffffff] {
              ro section .cstartup, block ROM_CONTENT };
    "RAM": place in [from 0x20020040 to 0x209fffff] { block RAM_CONTENT };

      Section                Kind        Address      Size  Object
      -------                ----        -------      ----  ------
    "ROM":                                        0x2405e0
      ROM_CONTENT                     0x18080040  0x2405e0  <Block>
        .text                ro code  0x18080040     0x104  access.o [8]
        .text                ro code  0x18080144     0x18c  cstartup.o [1]

这里发生了什么?我才刚刚开始了解链接器的作用,所以我对这一切还很陌生。

此外,为了进一步说明,两个 .intvec 部分包含相同的中断向量 table:

            SECTION .intvec:CODE:NOROOT(2)
            ...

    __vector:                       ; Make this a DATA label, so that stack usage
                                    ; analysis doesn't consider it an uncalled fun

            ARM

            ; All default exception handlers (except reset) are
            ; defined as weak symbol definitions.
            ; If a handler is defined by the application it will take precedence.
            LDR     PC,Reset_Addr           ; Reset
            LDR     PC,Undefined_Addr       ; Undefined instructions
            LDR     PC,SWI_Addr             ; Software interrupt (SWI/SVC)
            LDR     PC,Prefetch_Addr        ; Prefetch abort
            LDR     PC,Abort_Addr           ; Data abort
            DCD     0                       ; RESERVED
            LDR     PC,IRQ_Addr             ; IRQ
            LDR     PC,FIQ_Addr             ; FIQ

看来答案比我想象的要明显很多。根据“IAR C/C++ Development Guide”中的"Linking—an overview"节,IAR的链接器软件ILINK会忽略重复的节。因此,如果某个部分已在一个二进制对象或 ILINK 配置文件 (ICF) 中引用,则忽略所有其他对它的引用。

在此项目中,由于引导加载程序优先(在应用程序 [在项目的 .board 文件中定义;更多信息 here])之前加载和闪存,应用程序代码的 .intvec 被视为重复项,因此是 ignored/discarded.