我正在开发 Arm 裸机应用程序,并且我用以下标记标记了一些部分NOLOAD
。根据中的解释了解嵌入式软件中的链接描述文件 NOLOAD 部分 https://stackoverflow.com/q/57181652/6271889,我期望生成的 ELF 文件为not这些部分有一个可加载的段(程序头),但确实如此。
它是否正确?为什么这些部分在 ELF 文件中被标记为可加载?
由于链接器仍在将数据放入.bss
,加载程序应该如何知道不应加载这些部分?或者我是否错过了“负载”的含义NOLOAD
只对已初始化符号(通常会被放入.data
)?
这是我的链接器脚本的一部分:
.bss (NOLOAD) :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss_begin .bss_begin.*)
*(.bss .bss.*)
*(COMMON)
*(.bss_end .bss_end.*)
. = ALIGN(4);
__bss_end__ = .;
} >DRAM
.noinit (NOLOAD) :
{
. = ALIGN(4);
__noinit_start__ = .;
*(.noinit .noinit.*)
. = ALIGN(4) ;
__noinit_end__ = .;
} > DRAM
/* Check if there is enough space to allocate the main stack */
._stack (NOLOAD) :
{
. = ALIGN(4);
. = . + __Main_Stack_Size ;
. = ALIGN(4);
} >DRAM
这是输出 ELF 文件:
arm-none-eabi-readelf.exe -l test.elf
Elf file type is EXEC (Executable file)
Entry point 0x601b9
There are 2 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x010000 0x00060000 0x00060000 0x06840 0x06840 RWE 0x10000
LOAD 0x020000 0x20010000 0x20010000 0x00000 0x06084 RW 0x10000
Section to Segment mapping:
Segment Sections...
00 .text .ARM.exidx.reset .data
01 .systemclock .bss ._stack
为什么是.bss
and ._stack
那里的部分?
Thanks!!
第二段的FileSiz为0,这意味着没有数据将从elf文件加载到该段中。
该段存在于表中的原因是,在非嵌入式系统上,程序加载器仍然需要为该段中的段请求内存,并使用相关属性(在本例中为可读和可写)标记相关页面。
编辑:再次阅读问题后,我做了更多实验,似乎所有(NOLOAD)
似乎要做的是将输出文件中的节的类型设置为SHT_NOBITS
。 elf 规范将其称为不占用文件空间但仍然是程序内存映像的一部分的部分。
如果目标是在加载程序之前链接到 ROM 中已存在的代码,则应在任何部分之外的链接描述文件中定义这些符号。例如。already_present_code = 0x06000000; SECTIONS { .text : {*(.text*)} /* ... */}
。这似乎达到了预期的效果。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)