1. Documentation officielle pour accéder aux variables linkerscript dans votre code source :
Voir les exemples au bas de cette page : https://sourceware.org/binutils/docs/ld/Source-Code-Reference.html
Par conséquent, lorsque vous utilisez un symbole défini par le linker script dans le code source, vous devez toujours prendre l'adresse du symbole, et ne jamais essayer d'utiliser sa valeur. Par exemple, supposons que vous voulez copier le contenu d'une section de mémoire appelée .ROM dans une section appelée .FLASH et que le script du linker contient ces déclarations :
start_of_ROM = .ROM;
end_of_ROM = .ROM + sizeof (.ROM);
start_of_FLASH = .FLASH;
Alors le code source C pour effectuer la copie serait :
extern char start_of_ROM, end_of_ROM, start_of_FLASH;
memcpy (& start_of_FLASH, & start_of_ROM, & end_of_ROM - & start_of_ROM);
Notez l'utilisation des opérateurs "&". Ceux-ci sont corrects. Alternativement, les symboles peuvent être traités comme des noms de vecteurs ou de tableaux et le code fonctionnera alors comme prévu :
(Mon approche préférée) :
extern char start_of_ROM[], end_of_ROM[], start_of_FLASH[];
memcpy (start_of_FLASH, start_of_ROM, end_of_ROM - start_of_ROM);
Notez que l'utilisation de cette méthode ne nécessite pas l'utilisation des opérateurs '&'.
2. Votre cas spécifique :
Donc, si je voulais récupérer la valeur de la variable linkerscript __START_OF_PROG_MEMORY
pour l'utiliser dans mon programme C, je le ferais :
#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. Notez que si vous faites cela pour les microcontrôleurs STM32 :
Une autre astuce pour saisir l'adresse du début de la mémoire du programme (usu. Flash--d'où le début du programme est stocké) est de saisir simplement l'adresse de la balise g_pfnVectors
le tableau de la table vectorielle ISR globale, qui est défini dans votre fichier d'assemblage de démarrage (ex : "startup_stm32f746xx.s"). Pour cela, faites ce qui suit :
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á ! C'est magique :).
En rapport :