Ich hoffe, der Titel ist beschreibend genug. Also hier ist was ich machen möchte und womit ich gespielt habe.Schreiben von Daten auf bestimmte Adresse während der Kompilierung
Warten Sie, zuerst ist dies eine eingebettete Anwendung. Atmel SAM4L-Mikrocontroller, der die Atmel Studio IDE und den GCC Compiler/Linker verwendet.
Richtig, ich schreibe einen Bootloader, aber möchte die Bootloader-Version im Programmspeicher bis zum Ende des zugewiesenen Speicherplatzes für den Bootloader speichern (sagen wir 0x3FF0). Auf diese Weise kann die App auch die Bootloader-Version überprüfen, indem sie nur die spezifische Adresse anschaut. In diesem Moment bin ich beschäftigt mit einem Dienstprogramm für die App, um den Bootloader selbst zu aktualisieren, aber ich möchte nicht, dass die App oder der Bootloader die Version bei 0x3FF0 mit einem Befehl oder Code aktualisieren, ich will es als Teil der .bin/.hex Datei, wenn ich also den Bootloader auflee, wird die Version mit geblinkt. Also habe ich derzeit eine #define für den Bootloader-Typ, Hauptversion und Nebenversion, die alle in einer Datei globals.h im Projekt sind. Im Grunde möchte ich nur diese 3 Bytes zu 0x3FF0 schreiben, wenn ich kompiliere.
Wie ich es verstehe, gibt es ziemlich viele Tricks, die ich mit dem Linker ziehen kann, aber noch nie mit Linker-Skripten bis gestern gespielt habe und einige Dinge damit machen konnte, aber nicht, was ich noch will. Das Projekt erzeugt auch ein ziemlich intensives Linker-Skript, also bin ich auch ein wenig vorsichtig, wo ich hineinspringen und meine drei Bytes ausgeben kann. Ich weiß, dass Sie den Adresszeiger nicht zurück bewegen dürfen.
Hier ist die Linker-Skript durch das Projekt erzeugt
/**
* \file
*
* \brief Flash Linker script for SAM.
*
* Copyright (c) 2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)
/*
* NOTE: to keep binary compatibility with SAM4L4 device on SAM4L Xplained Pro,
* we use SAM4L4 memory space here instead SAM4L8. You may change it if you are
* using SAM4L8 device.
*/
/* Memory Spaces Definitions */
MEMORY
{
rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 /* flash, 256K */
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 /* sram, 32K */
/* rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000 */ /* flash, 512K */
/* ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00010000 */ /* sram, 64K */
}
/* The stack size used by the application. NOTE: you need to adjust according to your application. */
__stack_size__ = DEFINED(__stack_size__) ? __stack_size__ : 0x1000;
__ram_end__ = ORIGIN(ram) + LENGTH(ram) - 4;
/* Section Definitions */
SECTIONS
{
.text :
{
. = ALIGN(4);
_sfixed = .;
KEEP(*(.vectors .vectors.*))
*(.text .text.* .gnu.linkonce.t.*)
*(.glue_7t) *(.glue_7)
*(.rodata .rodata* .gnu.linkonce.r.*)
*(.ARM.extab* .gnu.linkonce.armextab.*)
/* Support C constructors, and C destructors in both user code
and the C library. This also provides support for C++ code. */
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
. = ALIGN(0x4);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
. = ALIGN(4);
KEEP(*(.fini))
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
. = ALIGN(4);
_efixed = .; /* End of text section */
} > rom
/* .ARM.exidx is sorted, so has to go in its own output section. */
PROVIDE_HIDDEN (__exidx_start = .);
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > rom
PROVIDE_HIDDEN (__exidx_end = .);
. = ALIGN(4);
_etext = .;
.relocate : AT (_etext)
{
. = ALIGN(4);
_srelocate = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_erelocate = .;
} > ram
/* .bss section which is used for uninitialized data */
.bss (NOLOAD) :
{
. = ALIGN(4);
_sbss = . ;
_szero = .;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = . ;
_ezero = .;
} > ram
/* stack section */
.stack (NOLOAD):
{
. = ALIGN(8);
_sstack = .;
. = . + __stack_size__;
. = ALIGN(8);
_estack = .;
} > ram
. = ALIGN(4);
_end = . ;
}
So so weit wie ich es verstehe, ist .ARM.exidx der letzte Abschnitt in ROM platziert und .relocate wird (von 0x20000000 weiter in RAM platziert wird) basierend auf den Regionen und MEMORY-Deklarationen, so dass meine drei Bytes irgendwo zwischen diesen beiden liegen sollten.
Dann, wie habe ich dieses Beispiel versucht http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0803a/BABDJCAA.html aber ich sehe es nicht in meinem .bin oder .hex Dateien wider. Ich nehme an, dass es nur den Speicher zuweist und tatsächlich nichts lädt, da es nur eine Variable ist. Ich habe auch Dinge wie diese gefunden gcc linker description file force symbol to be at specific address , aber ich nicht, da es nicht wirklich Code ich versuche, auf eine bestimmte Adresse zu laden, sehe ich nicht, wie ich diese Methode verwenden kann.
Ich spiele immer noch damit herum, das Linker-Skript zu manipulieren und zu sehen, was ich erreichen kann, aber jede Hilfe wäre sehr willkommen.
Wenn weitere Informationen erforderlich sind, fragen Sie bitte und ich werde zur Verfügung stellen. (Oder wenn ich den Titel oder die Tags für bessere Treffer ändern muss.)
Ich weiß nicht, wie gcc damit umgeht, aber mit anderen Toolchains gab es keinen großen Unterschied zwischen Funktionen und Variablen. Normalerweise wird die Platzierung auf die gleiche Weise durchgeführt. – user694733
Die beste Referenz für diese Information ist [** The ld Manual (sourceware) **] (https://sourceware.org/binutils/docs/ld/index.html). In Ihrem Fall mit eingebetteten Systemen oder mit Assembly selbst ist das Wissen um "ld" genauso wichtig wie die Kenntnis des Compilers selbst. Sieh dir an, ob du deine Frage etwas eingrenzen kannst. –
Danke, ich werde mich dort umsehen. – kowalski5233