linker - 非.bss未初始化数据部分

标签 linker elf ld initialization

我正在使用自定义链接器脚本将内核镜像分为两部分。第一个是普通代码和数据,第二个是初始化代码和不再需要时将被丢弃的数据。初始化部分也不像内核本身那样在地址空间之间共享,因此如果 fork() 仍然存在(处于开发的早期阶段),则任何内容都会在 fork() 上复制。

我已经分配了一个小的内核堆栈在启动时使用,但从我所看到的来看,我只能将它放在中的 .bss 部分,在地址空间之间共享或者在初始化区域中,不能将其存储为未初始化的数据。我想将其作为未初始化数据存储在图像的初始化部分,以便每个进程都有自己的副本。

我可以想到两种可能的方法来做到这一点,但我无法确定它们是否可能或我将如何告诉链接器执行它们。第一种是将未初始化的区域放在非 .bss 部分中,但我不确定这是否可能 - 我认为你不能混合这样的部分。第二个是创建第二个类似 .bss 的部分,该部分仅存储未初始化的数据,我可以将其放入链接器脚本的初始化部分中。

有什么想法吗?为了完整起见,这是我正在使用的链接器脚本:

ENTRY(_start)

_kernel_offset = _start_kernel - _start_kernel_phys;

SECTIONS {
    _start_init = 0x100000;

    .init _start_init : AT(ADDR(.init)) { *(.mboot .init*) }
    .ctors : {
        __CTOR_NUM__ = .; LONG((__CTOR_END__ - __CTOR_LIST__) / 4)
        __CTOR_LIST__ = .; *(.ctors*)
        __CTOR_END__ = .;
    }

    _end_init = .;

    . = ALIGN(4M);
    _start_kernel_phys = .;
    _start_kernel = 0xF0000000;

    .text _start_kernel : AT(ADDR(.text) - _kernel_offset) { *(.text*) }
    .data ALIGN(4K) : AT(ADDR(.data) - _kernel_offset) { *(.rodata* .data*) }
    .bss ALIGN(4K) : AT(ADDR(.bss) - _kernel_offset) { *(.bss) *(COMMON) }

    _end_kernel = .;
    _end_kernel_phys = _end_kernel - _kernel_offset;

    /DISCARD/ : { *(.eh_frame .comment) }
}

最佳答案

(呃,再次回答我自己的问题)

创建一个没有 CONTENTS 属性的新部分是可行的;它在程序集中声明如下:

.section .init.bss, "aw", @nobits

关于linker - 非.bss未初始化数据部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4261220/

相关文章:

linux - 通用 ELF 中的重定位 (EM : 183)

gcc - 将 llvm 生成的目标代码与 ld 链接起来

c++ - 数据文件的 ld 使数据大小成为 *ABS* 而不是整数

c++ - 在 VS2012 中使用时出现 log4cplus 链接错误

go - 从 go 二进制文件中的 TEXT 指令中删除文件路径

c++ - 解决 fortran 子例程的 C++ 包装器库之间的非唯一符号

c++ - C/C++ 与 GCC : Statically add resource files to executable/library

linux - 链接失败[ld找不到库]

c - 使用 Visual Studio 结合 Intel Fortran,如何解决使用不同类型的名称重整问题

c - 为 ARM 编译时出现 GCC 错误