我希望标题足够描述。所以这就是我想要做的以及我玩过的东西。
等等,首先,这是一个嵌入式应用程序。 Atmel SAM4L微控制器,使用Atmel Studio IDE和GCC编译器/链接器。
是的,我正在编写一个引导加载程序,但是想将引导加载程序版本保存到程序存储器中,直到引导加载程序的已分配空间的末尾(让我们说是0x3FF0)。这样,应用程序还可以通过查看特定地址来检查引导加载程序版本。 此时我正忙着为应用程序更新引导程序本身的实用程序,但我不希望应用程序或引导加载程序使用命令或代码在0x3FF0更新版本,我希望它作为.bin / .hex文件,所以当我启动引导加载程序时,版本会随之闪烁。 所以目前我有一个#define用于bootloader类型,主要版本和次要版本,它们都在项目中的globals.h文件中。基本上我只想在编译时将这3个字节写入0x3FF0。
据我了解,我可以通过链接器获取相当多的技巧,但直到昨天才使用链接器脚本,并且已经能够用它做一些事情,但不是我想要的然而。 该项目还创建了一个非常强大的链接器脚本,所以我也有点警惕在哪里跳转并转储我的三个字节。我知道你不允许移回地址指针。
这是项目生成的链接描述文件
/**
* \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 = . ;
}
据我了解,.ARM.exidx是放在ROM中的最后一个部分,而.relocate将根据区域和MEMORY声明放在RAM中(从0x20000000开始),所以我的三个字节应介于两者之间那两个。
然后,至于如何,我已经尝试了这个例子 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0803a/BABDJCAA.html 但是我没有看到它反映在我的.bin或.hex文件中。我猜测它只分配内存,并没有实际加载任何东西,因为它只是一个变量。 我也发现过这样的事情 gcc linker description file force symbol to be at specific address ,但我不是因为它不是真正的代码我试图加载到特定的地址,我不知道如何使用这种方法。
我仍在玩操纵链接器脚本并看到我能做到的事情,但是我们将非常感谢任何帮助。
如果需要任何进一步的信息,请询问,我会提供。 (或者,如果我需要更改标题或标签以获得更好的命中率。)
答案 0 :(得分:1)
事物的地址在链接器阶段确定,对于链接器,一切都只是符号。你的gcc linker description file force symbol to be at specific address 举例说明equaly适用于数据的函数。定义您的版本并将其放在C代码中的单独“版本”部分中。然后链接器可以将该部分放在某处。
现在困难的部分是将它带到rom的 end ,这意味着指定一个足够低的起始地址,该部分将在rom结尾处结束。使其固定大小(3字节)使这更简单。看看如何在链接描述文件中定义 ram_end 。对 rom_version_start 执行相同操作,但使用rom而不是ram并使用它来设置“版本”部分的开头使用'。 = rom_version_start ;'
答案 1 :(得分:1)
所以,对于那些寻找答案的人来说,这是我所做的更详细的例子。
在main.c中我定义了一个原型,首先让这个例子正常工作,之后我尝试了一个数组:
void jver(void) __attribute__((section(".jver")));
static uint8_t jvar[10] __attribute__((section(".jvar"))) = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
void jver(void)
{
//static uint8_t sbuf[10] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
jamba_TxBuff(jvar, 10);
}
然后,在链接描述文件中,在最后一个部分放在'rom'区域后,我在'rom'区域添加我要添加的东西:
_jverstart = 0x3FF0;
.jver : AT (_jverstart)
{
*(.jver)
} > rom
_jvarstart = 0x4100;
.jvar : AT (_jvarstart)
{
*(.jvar)
} > rom
请注意,我必须调整示例,只是使指针等于值不起作用。我必须创建一个变量并使用AT函数。在我的测试过程中,我添加了“rom”区域,如果我将其删除,则没有检查它是否仍然有效。
编译时,我得到以下结果:
:103FF00008B502480A21024B984708BDA02D0000D1
:04400000310D00007E
:0C410000303132333435363738390000A6
:0400000300001A657A
:00000001FF
从最后一个代码到0x3FF0,.bin文件填充0x00,然后是我的jver(void)函数的代码的几个字节(这可能只是对jamba_TxBuff函数的调用),然后填充0x00的所有方式到0x4100,其中“0123456789”。繁荣!!!我现在要添加的是链接器脚本中的'FILL'函数,用0xFF而不是0x00填充。
再次感谢您的参考和建议。