我有一个像这样的链接器脚本:
OUTPUT_FORMAT(binary)
SECTIONS
{
. = 0xFFFF800000000000 ;
.startup_text : { processor.o(.text) }
.text : { *(EXCLUDE_FILE (processor.o) .text) }
.data : { *(.data) }
.rodata : { *(.rodata) }
linker_first_free_page = ALIGN(4096);
}
一段代码加载此脚本生成的可执行文件,打印这些信息:
size of executable (pages) 3
first free page 0xffff800000003000
可执行文件本身打印:
&(linker_first_free_page) 0xffff800000003000
所以到目前为止一切都很好。现在我的可执行文件需要一个
.bss
部分。请注意,我没有能够加载 elf 文件的加载器,因此我需要一个可以读取和使用的平面二进制文件,其中包含所有部分。
第一次尝试
OUTPUT_FORMAT(binary)
SECTIONS
{
. = 0xFFFF800000000000 ;
.startup_text : { processor.o(.text) }
.text : { *(EXCLUDE_FILE (processor.o) .text) }
.data : { *(.data) }
.rodata : { *(.rodata) }
.bss : { *(.bss) }
linker_first_free_page = ALIGN(4096);
}
也就是说,只需添加一个
.bss
部分即可。这是输出:
size of executable (pages) 3
first free page 0xffff800000003000
&(linker_first_free_page) 0xffff800000004000
也就是说,链接器变量已正确更新,但该部分未分配(我想这对于
.bss
部分来说很正常)。
第二次尝试
OUTPUT_FORMAT(binary)
SECTIONS
{
. = 0xFFFF800000000000 ;
.startup_text : { processor.o(.text) }
.text : { *(EXCLUDE_FILE (processor.o) .text) }
.data : { *(.data) *(.bss) }
.rodata : { *(.rodata) }
linker_first_free_page = ALIGN(4096);
}
即将
.bss
部分放在 .data
部分内。这是输出:
size of executable (pages) 4
first free page 0xffff800000004000
&(linker_first_free_page) 0xffff800000003000
也就是说,
.bss
被分配了,但是链接器变量没有更新(我不明白为什么......)
简短的问题
那么,考虑到上述所有内容,如何将
.bss
部分嵌入到平面二进制文件中,以便它可以像“标准”文件一样加载到内存中并直接使用,而不需要特定的加载器?
Michael Petch 的评论给了我答案的见解:
OUTPUT_FORMAT(binary)
SECTIONS
{
. = 0xFFFF800000000000 ;
.startup_text : { processor.o(.text) }
.text : { *(EXCLUDE_FILE (processor.o) .text) }
.data : { *(.data) }
.rodata : { *(.rodata) }
.bss : { *(.bss) }
.fake : { . = . + SIZEOF(.bss); }
linker_first_free_page = ALIGN(4096);
}