如何使用gcc / ld将目标文件链接到原始二进制文件?

问题描述 投票:0回答:1

2019年12月2日更新:

我在使用m68k-elf工具链时遇到麻烦。我想做的就是翻译一个简单的68k汇编文件source.s,如下所示:

    .text 
    move.w %d0,%d1

进入目标文件,然后使用链接程序脚本memmap.ldscript

MEMORY 
{
    ROM1 (rx) : ORIGIN = 0x00, LENGTH = 16
    ROM2 (rx) : ORIGIN = 0x10, LENGTH = 16
}

SECTIONS 
{
    .text : 
    {
       *(.text)
    } >ROM2
}

OUTPUT_FORMAT(binary)

将此目标文件链接为原始二进制文件。最终文件应如下所示(在十六进制编辑器中查看):

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00

如果我这样构建它

m68k-elf-as -o source.o source.s 
m68k-elf-ld -T memmap.ldscript -o final.rom source.o 

然后final.rom仅包含:

30 01

因此,该节的代码位于0x00而不是0x05。

我需要“原始”机器代码才能刻录到E(E)PROM上。但是我想使用链接器和链接器脚本,以便将多个源文件中的节组装成目标文件,然后将它们链接到一个最终的ROM中,并由链接器脚本控制节的位置。使用m68k-elf可以吗?

assembly ld 68000
1个回答
0
投票

您需要通过创建包含某些内容的输出节来强制链接器发出ROM1区域。 manual says

其他在输出节中分配空间的链接脚本指令也将创建输出节。即使赋值不产生空格,除′以外,赋值也将加点。 = 0’,‘。 =。 + 0”,“。 = sym’,‘。 =。 + sym”和“。 = ALIGN(。!= 0,expr,1)”,即“ sym”是脚本中定义的值为0的绝对符号。这样一来,您就可以用'强制输出空白部分。 =。’。

所以这应该起作用:

MEMORY 
{
    ROM1 (rx) : ORIGIN = 0x00, LENGTH = 16
    ROM2 (rx) : ORIGIN = 0x10, LENGTH = 16
}

SECTIONS
{
    .dummy :
    {
       . = ORIGIN(ROM1) + LENGTH(ROM1);
    } >ROM1

    .text : 
    {
       *(.text)
       . = ORIGIN(ROM2) + LENGTH(ROM2);
    } >ROM2
}

OUTPUT_FORMAT(binary)

但是,至少在我的binutils 2.33.1版本中没有。 .=.也不起作用。如果您只需要填充区域,则可以向其中发送一些数据,例如由BYTE(0)指令执行,并且有效:

MEMORY 
{
    ROM1 (rx) : ORIGIN = 0x00, LENGTH = 16
    ROM2 (rx) : ORIGIN = 0x10, LENGTH = 16
}

SECTIONS
{
    .dummy :
    {
       BYTE(0);
       . = ORIGIN(ROM1) + LENGTH(ROM1);
    } >ROM1

    .text : 
    {
       *(.text)
       . = ORIGIN(ROM2) + LENGTH(ROM2);
    } >ROM2
}

OUTPUT_FORMAT(binary)

如果您确实有ROM1的某些内容,那么当然要为其创建输入部分,但请确保它始终存在,否则链接程序将其删除。奇怪的是,即使是零尺寸的部分也可以工作。

© www.soinside.com 2019 - 2024. All rights reserved.