Building Bare-Metal ARM Systems with GNU: Part 3
来源:互联网 发布:淘宝店铺排名靠前 编辑:程序博客网 时间:2024/04/29 13:33
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. The C version of the example for this article is located in the c_blinky directory, while the C++ version in the cpp_blinky directory.
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 to execute 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-chip flash 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 0x40 bytes 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 to copy 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 the compiler 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 map file 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 to What's needed to get started.
To read Part 2, go to Startup Code and the Low-level Initialization.
To download the C and C++ source code associated with this article series, go to Embedded.com's Downloadable Code page, or go to Blinky for C and Blinky for C++ to download the Zip files.
Miro Samek, Ph.D., is president of Quantum 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 the CodeSourcery Toolchain for ARM..
[3] ARM Projects
- Building Bare-Metal ARM Systems with GNU: Part 3
- Preparing Images for Bare Metal nodes using OpenStack Cloud: Bare-metal provisioning, Part 3
- Placement control and multi-tenancy isolation with OpenStack Cloud: Bare Metal Provisioning, Part 2
- Metron学习11_Metron with HDP 2.5 bare-metal install
- Building Telephony Systems with Asterisk
- Building Telephony Systems with OpenSER
- KVM: Bare-Metal Hypervisor?
- 10010.Building Tiny Linux Systems with Busybox
- Building Java Enterprise Systems with J2EE
- zk--Building Distributed Systems with ZooKeeper(58)
- Beyond Virtual Machines and Hypervisors: Overview of Bare Metal Provisioning with OpenStack Cloud
- Beyond Virtual Machines and Hypervisors: Overview of Bare Metal Provisioning with OpenStack Cloud
- BootIt Bare Metal 之 备份系统
- BootIt Bare Metal 之 硬盘分区篇
- BootIt Bare Metal 之安装到电脑
- Metal Bare嵌入式软件架构小谈
- 云计算术语(二):bare metal environment
- 裸机(Bare Metal)安装CoreOS
- 锚点的使用(链接到网页中某个位置)
- sql money类型 2为小数
- UML序列,状态,类
- 支撑物联网和云计算的是中间件技术
- FlashPlayer9和AVM2的弹性跑道模型
- Building Bare-Metal ARM Systems with GNU: Part 3
- Spring mvc 入门
- main函数返回值作用
- xp启动ODBC数据源管理器
- UML的基本构造块
- 无线数传模块
- 不用W3C标准的html
- 为什么不应该使用“volatile”类型
- 汇编程序的进制转换