【问题标题】:How to to build a binary into a image at a fixed address 0x80000?如何将二进制文件构建到固定地址 0x80000 的图像中?
【发布时间】:2020-04-10 13:40:57
【问题描述】:

在我们的 c 项目中,我们需要将二进制固件构建到一个固定文件偏移量 0x80000 的映像中。

然后当图像加载到内存中。我们可以将固件从偏移量 0x80000 加载到指定地址。 同时,由于固件位于文件偏移0x80000,我们可以独立升级固件。

所以我正在尝试使用 GNU 链接器脚本来实现它。 我现在要做的是使用 incbin 将我的二进制文件包含在 asm 文件中。 在链接器脚本中,我的代码是:

       .fw_image_start : {
                *(.__fw_image_start)
        }

       .fw_image : {
              KEEP(*(.fw_image))
        }

       .fw_image_end : {
                *(.__fw_image_end)
        }

然后我可以使用 fw_image_start 在镜像代码中加载固件。

但我仍然找不到将固件二进制文件放入最终映像中偏移量 0x80000 的方法。

你能帮我解决这个问题吗?

提前谢谢你!

【问题讨论】:

    标签: c arm gnu ld linker-scripts


    【解决方案1】:

    当您查看 GNU 的文档和示例时,您发现了什么?其中一些无疑是令人困惑或误导的,但有些很容易。这应该至少有一种方法可以解决问题(有多种方法可以解决您的问题)。

    novectors.s

    .global _start
    _start:
        bl notmain
        b .
    
    .globl bounce
    bounce:
        bx lr
    
    .section .hello_world
    .word 1,2,3,4
    

    notmain.c

    void bounce ( unsigned int );
    unsigned int mybss[8];
    int notmain ( void )
    {
        unsigned int ra;
    
        for(ra=0;ra<1000;ra++) bounce(ra);
    
        return(0);
    }
    

    memmap.ld

    MEMORY
    {
        ram : ORIGIN = 0x80000, LENGTH = 0x1000
    }
    SECTIONS
    {
        .text : { *(.text*) } > ram
        .rodata : { *(.rodata*) } > ram
        .hello_world : { *(.hello_world) } > ram
        .bss : { *(.bss*) } > ram
    }
    

    构建

    arm-none-eabi-as --warn --fatal-warnings  novectors.s -o novectors.o
    arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding -c notmain.c -o notmain.o
    arm-none-eabi-ld -o notmain.elf -T memmap.ld novectors.o notmain.o
    arm-none-eabi-objdump -D notmain.elf > notmain.list
    arm-none-eabi-objcopy notmain.elf notmain.bin -O binary
    

    检查结果

    Disassembly of section .text:
    
    00080000 <_start>:
       80000:   eb000001    bl  8000c <notmain>
       80004:   eafffffe    b   80004 <_start+0x4>
    
    00080008 <bounce>:
       80008:   e12fff1e    bx  lr
    
    0008000c <notmain>:
       8000c:   e92d4010    push    {r4, lr}
       80010:   e3a04000    mov r4, #0
       80014:   e1a00004    mov r0, r4
       80018:   e2844001    add r4, r4, #1
       8001c:   ebfffff9    bl  80008 <bounce>
       80020:   e3540ffa    cmp r4, #1000   ; 0x3e8
       80024:   1afffffa    bne 80014 <notmain+0x8>
       80028:   e3a00000    mov r0, #0
       8002c:   e8bd4010    pop {r4, lr}
       80030:   e12fff1e    bx  lr
    
    Disassembly of section .hello_world:
    
    00080034 <.hello_world>:
       80034:   00000001    andeq   r0, r0, r1
       80038:   00000002    andeq   r0, r0, r2
       8003c:   00000003    andeq   r0, r0, r3
       80040:   00000004    andeq   r0, r0, r4
    
    Disassembly of section .bss:
    
    00080034 <mybss>:
        ...
    

    自然:

    MEMORY
    {
        bob : ORIGIN = 0x80000, LENGTH = 0x1000
        ted : ORIGIN = 0xB0000, LENGTH = 0x1000
    }
    SECTIONS
    {
        .text : { *(.text*) } > bob
        .rodata : { *(.rodata*) } > bob
        .hello_world : { *(.hello_world) } > ted
        .bss : { *(.bss*) } > ted
    }
    

    给予

    Disassembly of section .text:
    
    00080000 <_start>:
       80000:   eb000001    bl  8000c <notmain>
       80004:   eafffffe    b   80004 <_start+0x4>
    
    00080008 <bounce>:
       80008:   e12fff1e    bx  lr
    
    0008000c <notmain>:
       8000c:   e92d4010    push    {r4, lr}
       80010:   e3a04000    mov r4, #0
       80014:   e1a00004    mov r0, r4
       80018:   e2844001    add r4, r4, #1
       8001c:   ebfffff9    bl  80008 <bounce>
       80020:   e3540ffa    cmp r4, #1000   ; 0x3e8
       80024:   1afffffa    bne 80014 <notmain+0x8>
       80028:   e3a00000    mov r0, #0
       8002c:   e8bd4010    pop {r4, lr}
       80030:   e12fff1e    bx  lr
    
    Disassembly of section .hello_world:
    
    000b0000 <.hello_world>:
       b0000:   00000001    andeq   r0, r0, r1
       b0004:   00000002    andeq   r0, r0, r2
       b0008:   00000003    andeq   r0, r0, r3
       b000c:   00000004    andeq   r0, r0, r4
    
    Disassembly of section .bss:
    
    000b0000 <mybss>:
        ...
    

    并且正如演示的那样,名称 ram、rom 等并不特殊,可以将其称为其他名称,例如 bob、ted、alice...我假设有些保留字您不能使用。

    同样有很多解决方案,请参阅 GNU 文档,我喜欢这种方法,因为它对我来说更好读,但您会看到跳过 MEMORY 部分的解决方案。

    (不,这不是完全正确的代码,而是演示了汇编语言引导程序、C 代码和链接器脚本)。

    【讨论】:

    • 非常感谢您的回复。但我的意思是将二进制文件放在输出映像中的 0x80000 处,而不是 VMA 地址。例如,没有固件二进制文件,原始图像是 200K。固件二进制文件为 100K。然后我需要创建一个组合输出图像,如: -- -- 。
    • 这只是 arm...objcopy -O 二进制输入,一旦你有你的链接描述文件。请参阅上面的后一个示例 .bin 文件在第一个定义的地址空间和另一个定义的地址空间之间有填充。您可以根据需要制作任意数量的这些。如果您尝试在一个二进制文件中执行两个程序,则构建两个单独的二进制文件要简单得多,然后编写 5-10 行程序将它们组合成您想要的输出。比试图让 gnu 去做的工作和痛苦要少得多。
    • 我知道如何将它与linux下的cat命令结合起来。但是在第一张图片的代码中,我需要使用 fw_image_start 值来读取二进制数据。这就是为什么我使用 incbin 将二进制数据添加到输出图像中。
    • 在没有 gnu 噩梦的情况下解决这个问题的各种方法,不是建议猫,这既不可靠也不可取。只需几行/十几行 C ......比 gnu ld 容易得多。但是对于 gnu ld 和其他 stackoverflow 问题一样,您可能必须将第二张图像中的所有对象拉入链接器脚本。
    猜你喜欢
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-08
    • 2022-07-19
    • 1970-01-01
    • 1970-01-01
    • 2011-08-20
    相关资源
    最近更新 更多