如何从C获取ld链接程序脚本中定义的变量的值 [英] How to get value of variable defined in ld linker script from C

查看:232
本文介绍了如何从C获取ld链接程序脚本中定义的变量的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个程序来运行裸机.我试图从自定义链接脚本中获取一个变量,以供在C中使用,这是我尝试过的.

I am writing a program to run bare metal. I am trying to get a variable from a custom linker script to use in C here is what I have attempted.

来自C:

extern unsigned long* __START_OF_PROG_MEMORY;
volatile unsigned long *StartOfProgram = (unsigned long*) (&__START_OF_PROG_MEMORY);

链接描述文件:

SECTIONS
{
    . = 0x80000;
    PROVIDE(__START_OF_PROG_MEMORY = .);
    .text : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) }
    .rodata : { *(.rodata .rodata.* .gnu.linkonce.r*) }
    PROVIDE(_data = .);
    .data : { *(.data .data.* .gnu.linkonce.d*) }
    .bss (NOLOAD) : {
        . = ALIGN(16);
        __bss_start = .;
        *(.bss .bss.*)
        *(COMMON)
        __bss_end = .;
    }
    _end = .;
    PROVIDE(__END_OF_PROG_MEMORY = .);

   /DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
}
__bss_size = (__bss_end - __bss_start)>>3;

获取链接描述文件中定义的变量内容的正确方法是吗?

Is the the correct way to get the contents of the variable defined in the linker script?

推荐答案

1.访问源代码中的链接描述文件变量的官方文档:

请参阅本页底部的示例: https://sourceware.org/binutils/docs/ld/Source- Code-Reference.html

1. Official documentation to access linkerscript variables in your source code:

See examples at the bottom of this page: https://sourceware.org/binutils/docs/ld/Source-Code-Reference.html

因此,当您在源代码中使用链接器脚本定义的符号时,应始终获取符号的地址,并且切勿尝试使用其值.例如,假设您要将一个名为.ROM的内存段的内容复制到一个名为.FLASH的段中,并且链接脚本包含以下声明:

Hence when you are using a linker script defined symbol in source code you should always take the address of the symbol, and never attempt to use its value. For example suppose you want to copy the contents of a section of memory called .ROM into a section called .FLASH and the linker script contains these declarations:

  start_of_ROM   = .ROM;
  end_of_ROM     = .ROM + sizeof (.ROM);
  start_of_FLASH = .FLASH;

然后执行复制的C源代码为:

Then the C source code to perform the copy would be:

  extern char start_of_ROM, end_of_ROM, start_of_FLASH;

  memcpy (& start_of_FLASH, & start_of_ROM, & end_of_ROM - & start_of_ROM);

请注意使用&"运算符.这些是正确的.另外,也可以将符号视为向量或数组的名称,然后代码将再次按预期工作:

Note the use of the ‘&’ operators. These are correct. Alternatively the symbols can be treated as the names of vectors or arrays and then the code will again work as expected:

(我的首选方法):

  extern char start_of_ROM[], end_of_ROM[], start_of_FLASH[];

  memcpy (start_of_FLASH, start_of_ROM, end_of_ROM - start_of_ROM);

请注意,使用此方法不需要使用'&'运算符.

Note how using this method does not require the use of ‘&’ operators.

2.您的具体情况:

因此,如果我想获取链接程序变量__START_OF_PROG_MEMORY的值以在我的C程序中使用,我会这样做:

2. Your specific case:

So, if I wanted to grab the value of the linkerscript variable __START_OF_PROG_MEMORY for use in my C program, I'd do:

#include <stdint.h>

extern uint32_t __START_OF_PROG_MEMORY[]; // linkerscript variable; NOT an array; `[]` is required to access a linkerscript variable like a normal variable--see here: https://sourceware.org/binutils/docs/ld/Source-Code-Reference.html
uint32_t start_of_program = (uint32_t)__START_OF_PROG_MEMORY;

3.请注意,如果您要对STM32微控制器执行此操作:

获取程序存储器起始地址(例如Flash,即存储程序起始位置)的另一种技巧是简单地获取g_pfnVectors全局ISR向量表数组的地址,该地址在启动程序集文件中定义(例如:"startup_stm32f746xx.s").为此,请执行以下操作:

3. Note that if you're doing this for STM32 microcontrollers:

Another trick to grab the address of the start of the program memory (usu. Flash--from where the start of the program is stored) is to simply grab the address of the g_pfnVectors global ISR vector table array, which is defined in your startup assembly file (ex: "startup_stm32f746xx.s"). To do that, do the following:

extern uint32_t g_pfnVectors[];  // true array (vector table of all ISRs), from the startup assembly .s file
uint32_t application_start_address = (uint32_t)&g_pfnVectors[0]; // Get the address of the first element of this array and cast it to a 4-byte unsigned integer

Voilá!太神奇了:).

Voilá! It's magical :).

  • [See both the Question & Answer here for excellent info & more examples!] Is accessing the "value" of a linker script variable undefined behavior in C?
  • Why do STM32 gcc linker scripts automatically discard all input sections from these standard libraries: libc.a, libm.a, libgcc.a?

这篇关于如何从C获取ld链接程序脚本中定义的变量的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆