简体   繁体   English

为什么使用此 linker 脚本在 bss 之外定义零初始化全局变量?

[英]Why are zero-initialized globals defined outside of bss using this linker script?

I have the following two variables, KMEM_END and MEM_TOP :我有以下两个变量, KMEM_ENDMEM_TOP

extern char _kernel_mem_end[];
extern char _physical_mem_end[];

uint64_t KMEM_END;
uint64_t MEM_TOP;

void kmem_init()
{
    kprintf("\nkmem_end: %p\n", (uint64_t) _kernel_mem_end);
    kprintf("phys_top: %p\n", (uint64_t) _physical_mem_end);

    kprintf("&KMEM_END: %p\n", &KMEM_END);
    kprintf("&MEM_TOP: %p\n", &MEM_TOP);

    // ...
}

I have _kernel_mem_end and _physical_mem_end provided by the linker script, here:我有_kernel_mem_end脚本提供的 _kernel_mem_end 和_physical_mem_end ,这里:

OUTPUT_ARCH("riscv");
ENTRY(start);

MEMORY {
 /* The -kernel QEMU option copies the image to that specific address. */
  ram (wxa) : ORIGIN = 0x80000000, LENGTH = 128M
}

SECTIONS {
    /* Starts at the address 0x80000000. */

    .text : ALIGN(4K) {
        PROVIDE(_text_start = .);
        *(.init)
        *(.text .text.*)
        . = ALIGN(4K);
        PROVIDE(_text_end = .);
    } >ram

    .data : ALIGN(4K) {
        PROVIDE(_data_start = .);
        *(.data .data.*)
        . = ALIGN(16);
        *(.sdata .sdata.*)
        . = ALIGN(4K);
        PROVIDE(_data_end = .);
    } >ram

    .rodata : ALIGN(4K) {
        PROVIDE(_rodata_start = .);
        *(.rodata .rodata.*)
        . = ALIGN(16);
        *(.srodata .srodata.*)
        . = ALIGN(4K);
        PROVIDE(_rodata_end = .);
    } >ram

    .bss : ALIGN(4K) {
        PROVIDE(_bss_start = .);
        *(.bss .bss.*)
        . = ALIGN(4K);
        PROVIDE(_stack_start = .);
        . += 0x10000;
        PROVIDE(_stack_end = .);
        PROVIDE(_bss_end = .);
    } >ram

    . = ALIGN(4K);

    PROVIDE(_kernel_mem_end = .);
    PROVIDE(_physical_mem_end = ORIGIN(ram) + LENGTH(ram));
} 

As the variables are globals and uninitialized (default-initialized to zero), I expect them to reside in the BSS section.由于变量是全局变量且未初始化(默认初始化为零),我希望它们驻留在 BSS 部分。 However, the output of kmem_init is as follows:但是kmem_init的kmem_init如下:

kmem_end: 80015000
phys_top: 88000000
&KMEM_END: 80015008
&MEM_TOP: 80015000

This means that the two variables reside between _kernel_mem_end and _physical_mem_end , which is not a "standard" section at all (most importantly, not bss.)这意味着这两个变量位于_kernel_mem_end_physical_mem_end之间,这根本不是“标准”部分(最重要的是,不是 bss。)

I get them to reside in the data section by initializing them to something other than zero, and that's fine for my purpose.我通过将它们初始化为非零的值来让它们驻留在数据部分中,这对我的目的来说很好。 I can initialize them to whatever as I will just override the initial value.我可以将它们初始化为任何值,因为我将覆盖初始值。 However, I want to know why does this happen?但是,我想知道为什么会这样?

GCC made those variables reside in .sbss , which I don't include in my "unified".bss section. GCC 使这些变量驻留在.sbss中,我不包括在我的“统一”.bss 部分中。

So using *(.bss.bss.*.sbss.sbss.*) instead of *(.bss.bss.*) fixed the issue.所以使用*(.bss.bss.*.sbss.sbss.*)而不是*(.bss.bss.*)解决了这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM