打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Part 3 - The Linker Script
Building Bare-Metal ARM Systems with GNU: Part 3 - The Linker Script
By Miro Samek, Quantum Leaps
Embedded.com
(07/10/07, 12:05:00 H EDT)
In this part I move on to describe theGNU linkerscript for a bare-metal ARM project. The code accompanying this article is available online at theEmbedded.com's Downloadable Code page. The recommended reading for this part includes "Embedded System Design on a Shoestring" by Lewin Edwards [1], specifically section "Ld—GNU Linker" in Chapter 3.
Linker Script
The linker script must match the startup code described in Part 2 of this article for all the section names and other linker symbols. The linker script cannot be generic, because it must define the specific memory map of the target device, as well as other application-specific information.
The linker script is therefore named here blinky.ld, which corresponds to the Blinky example application that blinks the 4 user LEDs of the AT91SAM7S-EK board. TheC version of the example for this article is located in the c_blinky directory, while theC++ version in the cpp_blinky directory.
Listing 1 Linker script for the Blinky example application (AT91SAM7S64 MCU).
Listing 1 above shows the linker script for the Blinky example application. The script is almost identical for C and C++ versions, with the minor differences discussed later in this section. The highlights of the linker script are as follows:
(1) The OUTPUT_FORMAT directive specifies the format of the output image (elf32, little-endian, ARM)
(2) OUTPUT_ARCH specifies the target machine architecture.
(3) ENTRY explicitly specifies the first instruction toexecute in a program
(4) The MEMORY command describes the location and size of blocks of memory in the target.
(5) The region ROM corresponds to the on-chipflash of the AT91SAM7S64 device. It can contain read-only and executable sections (rx), it starts at 0x00100000 and is 64KB in size.
(6) The region RAM corresponds to the on-chip SRAM of the AT91SAM7S64 device. It can contain read-only, read-write and executable sections (rwx), it starts at 0x00200000 and is 16KB in size.
(7) The following symbols denote the sizes of the ARM stacks. You need to adjust the sizes for your particular application. The C-stack cannot be zero.
(8) The SECTIONS command opens the definition of all the sections for the linker.
(9) The .reset section contains the startup code (including the ARM vectors) and must be located as the first section in ROM.
(10) This line locates all .text sections from the startup.o object module.
(11) The section size is aligned to the 4-byte boundary
(12) This section is loaded directly to the ROM region defined in the MEMORY command.
(13) The .ramvect section contains the RAM-based ARM vector table and the secondary jump table and must be loaded as the first section in RAM
(14) The ARM vector table and the secondary jump table have known size of 0x40 bytes. The current location counter is simply incremented to reserve 0x40bytes for the section.
(15) The .ramvect section goes into the RAM region.
(16) The .fastcode section is used for RAM-based code, which needs to be loaded to ROM, but copied and executed from RAM.
(17) The .fastcode section has different load memory address (LMA) than the virtual memory address (VMA). The symbol __fastcode_load corresponds to the LMA in ROM and is needed by the startup code tocopy the section from ROM to RAM.
(18) The __fastcode_start symbol corresponds to the VMA of the .fastcode section and is needed by the startup code to copy the section from ROM to RAM.
(19) The .glue_7t and .glue_7 sections are synthesized by thecompiler when you specify the ARM-THUMB interworking option. The sections contain the "call veneers" between THUMB and ARM code and are accessed frequently by every call between ARM and THUMB. It's typically advantageous to place this small amount of hot-spot code in RAM.
(20) The .text.fastcode section is assigned explicitly to individual functions in the C/C++ code by means of the __attribute__ ((section (".text.fastcode"))) command.
(21) The GNU compiler is also capable of placing each function in the separate section named after the function (requires specifying the option -ffunction-sections). This allows you to be very selective and to place individual functions (e.g. the function Blinky_shift()) in RAM.
NOTE: The C++ compiler performs function name-mangling and you need to consult the mapfile to figure out the section name assigned to a given function. For example, the class method Blinky::shift() is placed in the section .text._ZN6Blinky5shiftEv)
(22) You can place more hot-spot functions in RAM during the fine-tuning stage of the project.
(23) The .fastcode section is located in RAM, but is loaded at the ROM address.
(24) The .text section is for code and read-only data accessed in place.
(25) If you repeat sections already located in the .fastcode section, the earlier location will take precedence. However, if you decide to remove these sections from .fastcode, they will be located per the second specification.
(26) The following sections are synthesized by the GNU C++ compiler and are used for static constructors and destructors.
(27) The section .rodata is used for read-only (constant) data, such as look-up tables. Just as code, you might choose to place some frequently accessed constants in RAM by locating these sections in the .fastcode section.
(28) The .text section is located and loaded to ROM.
(29) The .ARM.exidx section is used for C++ exception handling. It is located here for completeness. Bare-metal ARM projects typically cannot afford the overhead associated with C++ exceptions handling.
(30) The .data section contains initialized data.
(31) The .data section is located in RAM, but is loaded to ROM and copied to RAM during startup.
(32) The .bss section contains uninitialized data. The C/C++ standard requires that this section must be cleared at startup.
(33) The .bss section is located in RAM only.
(34) The .stack section contains all the stacks. The section is initialized with a given bit-pattern at startup.
(35) The ARM GNU toolset uses full descending stack. Therefore the linker script provides only the top of stack symbols to initialize the various ARM stack pointers. In particular the C stack (SYS stack) is allocated at the end of the .stack section.
(36) The .stack section is located in RAM.
(37) The symbols _end, __end, and end are used to set up the beginning of the heap, if the heap is used.
(38) The following sections are for the debugger only and are never loaded to the target.
Coming Up Next
Next in Part 4, I'll describe the C and C++ compiler options as well as how to minimize the overhead of C++ using the GNU toolchain. Stay tuned.
To read Part 1, go toWhat's needed to get started.
To read Part 2, go toStartup Code and the Low-level Initialization.
To download the C and C++ source code associated with this article series, go toEmbedded.com's Downloadable Code page, or go toBlinky for C andBlinky for C++ to download the Zip files.
Miro Samek, Ph.D., is president ofQuantum Leaps, LLC. He can be contacted at miro@quantum-leaps.com.
References
[1] Lewin A.R.W. Edwards, "Embedded System Design on a Shoestring", Elsevier 2003.
[2]  GNU Linker (ld) HTML documentation included in theCodeSourcery Toolchain for ARM..
[3]ARM Projects
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
STM32 Developing with GCC tools
From .rodata to .rwdata – introduction to memory mapping and LD scripts – Guy on BITS
IAR EWARM软件软件配置
Scatter File的用法
浅析eCos系统Redboot单元启动流程
arm开发经验笔记(ZT)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服