GNU LD填充空链接器部分

时间:2016-04-07 08:26:34

标签: c gcc linker binutils

我正在使用GCC / binutils工具链为微控制器(MSP430系列)编写裸机代码,我想使用我的链接器脚本用“永远循环”操作码填充未使用的中断向量(在开发中,在生产中“SW重置”操作码)。我似乎无法实现这一点。

这是我的链接器脚本(或相关部分):

MEMORY {
  SFR              : ORIGIN = 0x0000, LENGTH = 0x0010 /* END=0x0010, size 16 */
  PERIPHERAL_8BIT  : ORIGIN = 0x0010, LENGTH = 0x00F0 /* END=0x0100, size 240 */
  PERIPHERAL_16BIT : ORIGIN = 0x0100, LENGTH = 0x0100 /* END=0x0200, size 256 */
  RAM              : ORIGIN = 0x1C00, LENGTH = 0x0800 /* END=0x23FF, size 2048 */
  INFOMEM          : ORIGIN = 0x1800, LENGTH = 0x0200 /* END=0x19FF, size 512 as 4 128-byte segments */
  INFOA            : ORIGIN = 0x1980, LENGTH = 0x0080 /* END=0x19FF, size 128 */
  INFOB            : ORIGIN = 0x1900, LENGTH = 0x0080 /* END=0x197F, size 128 */
  INFOC            : ORIGIN = 0x1880, LENGTH = 0x0080 /* END=0x18FF, size 128 */
  INFOD            : ORIGIN = 0x1800, LENGTH = 0x0080 /* END=0x187F, size 128 */
  FRAM (rxw)       : ORIGIN = 0x4400, LENGTH = 0xBB80 /* END=0xFF7F, size 48000 */
  VECT1            : ORIGIN = 0xFF90, LENGTH = 0x0002
  VECT2            : ORIGIN = 0xFF92, LENGTH = 0x0002
  VECT3            : ORIGIN = 0xFF94, LENGTH = 0x0002
  ... snip ...
  VECT54           : ORIGIN = 0xFFFA, LENGTH = 0x0002
  VECT55           : ORIGIN = 0xFFFC, LENGTH = 0x0002
  RESETVEC         : ORIGIN = 0xFFFE, LENGTH = 0x0002
  BSL              : ORIGIN = 0x1000, LENGTH = 0x0800
  HIFRAM (rxw)     : ORIGIN = 0x00010000, LENGTH = 0x00003FFF
}

SECTIONS
{
  __interrupt_vector_1   : { KEEP (*(__interrupt_vector_1 )) } > VECT1 =0x3C00
  __interrupt_vector_2   : { KEEP (*(__interrupt_vector_2 )) } > VECT2 =0x3C00
  __interrupt_vector_3   : { KEEP (*(__interrupt_vector_3 )) } > VECT3 =0x3C00
  __interrupt_vector_4   : { KEEP (*(__interrupt_vector_4 )) } > VECT4 =0x3C00
  __interrupt_vector_5   : { KEEP (*(__interrupt_vector_5 )) } > VECT5 =0x3C00
  __interrupt_vector_6   : { KEEP (*(__interrupt_vector_6 )) } > VECT6 =0x3C00
  ... snip ...
  __interrupt_vector_52  : { KEEP (*(__interrupt_vector_52)) KEEP (*(__interrupt_vector_timer0_b0)) } > VECT52 =0x3C00
  __interrupt_vector_53  : { KEEP (*(__interrupt_vector_53)) KEEP (*(__interrupt_vector_comp_e)) } > VECT53 =0x3C00
  __interrupt_vector_54  : { KEEP (*(__interrupt_vector_54)) KEEP (*(__interrupt_vector_unmi)) } > VECT54 =0x3C00
  __interrupt_vector_55  : { KEEP (*(__interrupt_vector_55)) KEEP (*(__interrupt_vector_sysnmi)) } > VECT55 =0x3C00
  __reset_vector :
  {
    KEEP (*(__interrupt_vector_56))
    KEEP (*(__interrupt_vector_reset))
    KEEP (*(.resetvec))
  } > RESETVEC
... and all the usual stuff, .data, .bss, etc ...

(0x3C00是“永远跳转”操作码)

如果输入上没有至少一个符号,则根本不会生成这些部分。

我试着乱搞。 =。;和类似的命令,即使在输入部分中没有任何内容时也可以创建部分,这有时会起作用,但是我需要生成的部分是PROGBITS类型并设置了A标志,否则它们将不会被加载到目标。我没有尝试过这种配置。

当输入部分什么都没有时,我该怎么做才能生成一个填充了0x3C00的部分,它是PROGBITS类型并设置了A标志?

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

你能使用SHORT(0x3C00)语法吗?

<execution>
                <id>exec-npm-update</id>
                <phase>generate-sources</phase>
                <configuration>
                  <workingDirectory>${uiResourcesDir}</workingDirectory>
                  <executable>npm.cmd</executable>
                  <arguments>
                    <argument>update</argument>
                  </arguments>
                </configuration>
                <goals>
                  <goal>exec</goal>
                </goals>
              </execution>

这告诉链接器将两个字节0x3C,00放入名为__interrupt_vector_1 : { SHORT(0x3C00) } > VECT1 的节中,该节在内存区__interrupt_vector_1中分配。我也不认为你需要VECT1指令。如果不使用,该部分的名称也可以是您想要的任何名称。在这种情况下,我通常将我的部分与我的记忆区域相匹配,例如。

KEEP

注意部分名称上的点。

您的.vect1 : { SHORT(0x3C00) } >vect1 也应该是:

VECT1

因为它是可执行代码。