Cre*_*ewe 7 arm compilation cortex-m3 stm32 linker-scripts
长话短说.我希望学习如何创建一个好的链接器脚本,这样我就可以更改平台/架构/供应商,我不会再知道该做什么而再次停留在零点.我并不关心任务的难度,而是关心它.
我已经开始了一个项目,就是为STM的32位Cortex-M3芯片编程和开发创建基础或骨架.在jsiei97的帮助下,从STM32F103RB开始(我还有TI Stellaris LM3S828,但这是另一个问题),无需经过许可的IDE.由于我是学生,而且大多数学生都买不起这样的东西.
我知道有ODev,Eclipse插件和什么不是,并且已经阅读了各种博客,wiki,docs/man页面,大多数项目为您提供了一个链接器脚本,几乎无法解释为什么以及在哪里定义了事物.
我已经为STM32编译了一个arm-none-eabi工具链,但我挂起的是链接器脚本.CodeSourcery也需要一个.我有一个基本的概念,如何在阅读gnu手册页后创建它们和它们的语法,但我根本没有线索从哪个开始添加除了显而易见的.text,.bss和.data之外的各种额外部分.
我创建了一个基本版本,但是我得到链接错误,要求分区定义,这就是我遇到的问题.我知道如何定义它们,但知道我正在做的事情是否接近正确就是问题所在.
我有一个简单的链接器脚本,我经常跨平台重用,只需根据需要更改一些地址.
有许多样本很多都带有gcc样本,其中大多数都有链接器脚本.
MEMORY
{
rom : ORIGIN = 0x00000000, LENGTH = 0x40000
ram : ORIGIN = 0x10000000, LENGTH = 30K
}
SECTIONS
{
.text : { *(.text*) } > rom
.bss : { *(.bss*) } > ram
}
Run Code Online (Sandbox Code Playgroud)
以下是 STM32F105RB 的工作链接器脚本(还有适用于 R8 和 RC 的版本):
https://github.com/anrope/stm-arp/blob/github/arp.rb.ld(文字如下)
我的首要猜测是你不需要改变任何东西。也许是 MEMORY{} 语句中定义的区域的起源。希望评论对您有所帮助。
我将它与我自己开发的 GNU/GCC 交叉编译器一起使用。nm编译后,运行代码以确保各部分放置在正确的地址会很有帮助。
编辑:我使用 GNU ld 文档将这个链接器脚本拼凑在一起:
http://sourceware.org/binutils/docs/ld/
并通过检查 GCC 与标准链接描述文件的交叉编译的输出,使用nm. 我基本上识别了正在输出的所有部分,并找出哪些部分实际上有用,以及它们应该在 STM32F105 的内存中存放在哪里。
我在链接描述文件中记录了每个部分的用途。
/*
arp.{r8,rb,rc}.ld :
These linker scripts (one for each memory density of the stm32f105) are used by
the linker to arrange program symbols and sections in memory. This is especially
important for sections like the interrupt vector, which must be placed where the
processor is hard-coded to look for it.
*/
/*stm32f105 dev board linker script*/
/*
OUTPUT_FORMAT() defines the BFD (binary file descriptor) format
OUTPUT_FORMAT(default, big, little)
*/
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
/* ENTRY() defines the symbol at which to begin executing code */
ENTRY(_start)
/* tell ld where to look for archive libraries */
/*SEARCH_DIR("/home/arp/stm/ctc/arm-eabi/lib")*/
/*SEARCH_DIR("/home/arp/stm/ccbuild/method2/install/arm-eabi/lib")*/
SEARCH_DIR("/home/arp/stm32dev-root/usrlol/arm-eabi/lib")
/*
MEMORY{} defines the memory regions of the target device,
and gives them an alias for use later in the linker script.
*/
/* stm32f105rb */
MEMORY
{
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 32k
flash (rx) : ORIGIN = 0x08000000, LENGTH = 128k
option_bytes_rom (rx) : ORIGIN = 0x1FFFF800, LENGTH = 16
}
_sheap = _ebss + 4;
_sstack = _ebss + 4;
/*placed __stack_base__ trying to figure out
global variable overwrite issue
__stack_base__ = _ebss + 4;*/
_eheap = ORIGIN(ram) + LENGTH(ram) - 1;
_estack = ORIGIN(ram) + LENGTH(ram) - 1;
/* SECTIONS{} defines all the ELF sections we want to create */
SECTIONS
{
/*
set . to an initial value (0 here).
. (dot) is the location counter. New sections are placed at the
location pointed to by the location counter, and the location counter
is automatically moved ahead the length of the new section. It is important
to maintain alignment (not handled automatically by the location counter).
*/
. = SEGMENT_START("text-segment", 0);
/*isr_vector contains the interrupt vector.
isr_vector is read only (could be write too?).
isr_vector must appear at start of flash (USR),
address 0x0800 0000*/
.isr_vector :
{
. = ALIGN(4);
_sisr_vector = .;
*(.isr_vector)
_eisr_vector = .;
} >flash
/*text contains executable code.
text is read and execute.*/
.text :
{
. = ALIGN(4);
*(.text)
. = ALIGN(4);
*(.text.*)
} >flash
/*init contains constructor functions
called before entering main. used by crt (?).*/
.init :
{
. = ALIGN(4);
KEEP(*(.init))
} >flash
/*fini contains destructor functions
called after leaving main. used by crt (?).*/
.fini :
{
. = ALIGN(4);
KEEP(*(.fini))
} >flash
/* rodata contains read only data.*/
.rodata :
{
. = ALIGN(4);
*(.rodata)
/* sidata contains the initial values
for variables in the data section.
sidata is read only.*/
. = ALIGN(4);
_sidata = .;
} >flash
/*data contains all initalized variables.
data is read and write.
.data (NOLOAD) : AT(_sidata)*/
.data : AT(_sidata)
{
. = ALIGN(4);
_sdata = .;
*(.data)
_edata = .;
} >ram
/*bss contains unintialized variables.
bss is read and write.
.bss (NOLOAD) :*/
.bss :
{
. = ALIGN(4);
_sbss = .;
__bss_start__ = .;
*(.bss)
. = ALIGN(4);
/*COMMON is a special section containing
uninitialized data.
Example: (declared globally)
int temp; //this will appear in COMMON */
*(COMMON)
_ebss = .;
__bss_end__ = .;
} >ram AT>flash
. = ALIGN(4);
end = .;
/* remove the debugging information from the standard libraries */
DISCARD :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6766 次 |
| 最近记录: |