gpt4 book ai didi

c - 为什么 objcopy 排除一个部分而不排除另一个部分?

转载 作者:太空宇宙 更新时间:2023-11-04 03:26:57 25 4
gpt4 key购买 nike

背景

我试图在我的 STM32 设备上使用一个特殊的 SRAM 部分,该部分位于地址 0x40006000 .我在 ST 的示例代码中看到的一种方法是简单地创建指针,其值恰好位于 RAM 的该部分内。我想要做的是让链接器为我管理该部分中的静态分配。

基本上,我会从这样的事情开始:

static uint16_t *buffer0 = ((uint16_t *)0x40006000);
static uint16_t *buffer1 = ((uint16_t *)0x40006080);

像这样的东西(我认为它不易碎,也不像 hacky,虽然不便携):

#define _PMA __attribute__((section(".pma"), aligned(2)))
static uint16_t _PMA buffer0[64];
static uint16_t _PMA buffer1[64];

为了实现这一点,我修改了我的链接描述文件,在 0x40006000 处添加了一个名为“PMA”的新内存。我在其中找到了“.pma”部分,如下所示:

MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
PMA (xrw) : ORIGIN = 0x40006000, LENGTH = 1024 /* This is the memory I added */
}

SECTIONS
{
.text
{
..blah blah blah..
} > FLASH

...more sections, like rodata and init_array..

/* Initialized data goes into RAM, load LMA copy after code */
.data
{
..blah blah blah with some linker symbols to denote the start and end..
} >RAM AT> FLASH

.bss
{
..blah blah blah..
} >RAM

.pma /* My new section! */
{
_pma_start = .;
. = ALIGN(2);
*(.pma)
*(.pma*)
} >PMA
}

发生了什么

所以这看起来一切都很好,花花公子,我的东西编译并且 map 向我显示 buffer0buffer1确实位于 0x400060000x40006080 .这是我的 makefile 最后一点的输出:

arm-none-eabi-gcc obj/usb_desc.o obj/usb_application.o obj/osc.o obj/usb.o obj/main.o obj/system_stm32f1xx.o obj/queue.o obj/list.o obj/heap_1.o obj/port.o obj/tasks.o obj/timers.o obj/startup_stm32f103x6.o -TSTM32F103X8_FLASH.ld -mthumb -mcpu=cortex-m3 --specs=nosys.specs -Wl,-Map,bin/blink.map -o bin/blink.elf
arm-none-eabi-objdump -D bin/blink.elf > bin/blink.lst
arm-none-eabi-size --format=SysV bin/blink.elf
bin/blink.elf :
section size addr
.isr_vector 268 134217728
.text 13504 134218000
.rodata 44 134231504
.ARM 8 134231548
.init_array 8 134231556
.fini_array 4 134231564
.data 1264 536870912
.jcr 4 536872176
.bss 1348 536872180
._user_heap_stack 1536 536873528
.pma 256 1073766400
.ARM.attributes 41 0
.debug_info 26748 0
.debug_abbrev 5331 0
.debug_aranges 368 0
.debug_line 5274 0
.debug_str 8123 0
.comment 29 0
.debug_frame 4988 0
Total 69146


arm-none-eabi-objcopy -R .stack -O binary bin/blink.elf bin/blink.bin

我看到了 .pma正如我预期的那样,使用了 256 个字节。地址看起来也是正确的。现在,当我 ls bin目录我对此表示欢迎:

-rwxr-xr-x 1 kevin users 939548800 Nov  2 00:04 blink.bin*
-rwxr-xr-x 1 kevin users 221528 Nov 2 00:04 blink.elf*

那个bin文件是我通过 openocd 加载到芯片闪存上的内容。它是从 0x08000000 开始的闪存图像。

旁注:实际上,在我意识到它有多大之前,我曾尝试将该 bin 文件加载到我的芯片上……这显然不起作用。

这是我删除 PMA 部分后得到的结果:

arm-none-eabi-size --format=SysV bin/blink.elf
bin/blink.elf :
section size addr
.isr_vector 268 134217728
.text 13504 134218000
.rodata 44 134231504
.ARM 8 134231548
.init_array 8 134231556
.fini_array 4 134231564
.data 1392 536870912
.jcr 4 536872304
.bss 1348 536872308
._user_heap_stack 1536 536873656
.ARM.attributes 41 0
.debug_info 26748 0
.debug_abbrev 5331 0
.debug_aranges 368 0
.debug_line 5274 0
.debug_str 8123 0
.comment 29 0
.debug_frame 4988 0
Total 69018

文件大小与我预期的完全一样:

-rwxr-xr-x 1 kevin users  15236 Nov  2 00:09 blink.bin
-rwxr-xr-x 1 kevin users 198132 Nov 2 00:09 blink.elf

问题

据我了解,这里发生的事情是 objcopy刚刚从 0x08000000 复制了所有内容至 0x400060FF进入那个bin文件。这显然不是我想要发生的。我预计它只会复制闪存。

现在,显然我只能说 -R .pma在我的 objcopy命令,一切都会快乐。然而,我很好奇的是如何objcopy知道不要复制.data进入二值图像。我注意到正在运行 objcopy -R .data与运行 objcopy 的结果完全相同没有那个。与 .bss 相同.这告诉我它不是 AT链接描述文件中的命令(这是我在 .data.bss 之间看到的唯一真正区别)

我能做些什么来制作我的 .pma部分的行为方式与 .data 相同或 .bss来自 objcopy的视角? .data 有什么有趣的事情发生吗?/.bss在我正在使用的中间 elf 文件中(参见上面生成 elf 文件的链接器命令)?

最佳答案

将您的部分定义为“.pma”很可能赋予它类型“PROGBITS”(使用 readelf 检查),这表示要加载到目标上的部分。

您想要/需要的是定义一个不必加载到目标上的部分,例如类型为“NOBITS”的“.bss”部分。

我经常使用以下部分定义来避免将某些缓冲区放入“.bss”部分(因为这会由于“.bss”部分的零初始化而减慢启动阶段):

static uint8_t uart1_buffer_rx[4096] __attribute__((section(".noinit,\"aw\",%nobits@")));

我不记得为什么我使用名称“.noinit”,但是这部分出现在“.bss”部分之后。

在您的情况下,在“.pma”部分声明之后添加“aw”和“nobits”标志可能会有所帮助。

关于c - 为什么 objcopy 排除一个部分而不排除另一个部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40372977/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com