|
| 1 | +/*===----------------------------------------------------------------------===*/ |
| 2 | +/* */ |
| 3 | +/* This source file is part of the Swift open source project */ |
| 4 | +/* */ |
| 5 | +/* Copyright (c) 2025 Apple Inc. and the Swift project authors. */ |
| 6 | +/* Licensed under Apache License v2.0 with Runtime Library Exception */ |
| 7 | +/* */ |
| 8 | +/* See https://swift.org/LICENSE.txt for license information */ |
| 9 | +/* */ |
| 10 | +/*===----------------------------------------------------------------------===*/ |
| 11 | + |
| 12 | +/* |
| 13 | + * This application uses ELF for linking, and uses the elf2hex.py post-processing tool for package the result into a |
| 14 | + * form suitable for flashing. The entire memory layout scheme (which this linker script participates in) is: |
| 15 | + * |
| 16 | + * - At normal application runtime, the expected memory layout is: |
| 17 | + * |
| 18 | + * - 0x08000000-0x08100000 (flash) ... code + read-only globals |
| 19 | + * - 0x20000000-0x20008000 (SRAM) ... stack |
| 20 | + * - 0x20008000-0x20030000 (SRAM) ... read-write globals, and bss (zero initialized globals) |
| 21 | + * - 0x20030000-0x20050000 (SRAM) ... heap |
| 22 | + * |
| 23 | + * - However, this layout cannot be flashed as is (because it uses the SRAM too), so a few more steps are needed. |
| 24 | + * |
| 25 | + * - In a linked ELF file, the memory locations of the sections match the expected runtime layout. The ELF file does not |
| 26 | + * contain the stack and the heap, so we don't have to worry about those (there is also no expectation that the memory |
| 27 | + * for those is zeroed out at program start). |
| 28 | + * |
| 29 | + * - The ELF file is given to the elf2hex.py tool, which will produce a .hex output, and we use the |
| 30 | + * --relocate-data-segment flag to relocate the read-write globals region (0x20008000-0x20030000) into the flash |
| 31 | + * region, concretely the region is appended at a 4-byte-aligned location after the other contents of the flash. |
| 32 | + * |
| 33 | + * - This is concretely achieved using the __flash_data_start+__flash_data_len and __data_start+__data_end symbols |
| 34 | + * defined in this linker script. The elf2hex.py script finds the addresses of these symbols and performs the |
| 35 | + * relocation of those bytes. |
| 36 | + * - Note that after the relocation, the segments in ELF headers (PT_LOAD commands) don't match the actual physical |
| 37 | + * layout. However, this relocation is reversed at early startup time, so that at "normal" runtime, the layout is |
| 38 | + * as expected. See below. |
| 39 | + * |
| 40 | + * - The ARM core loads the initial stack pointer, and initial program counter from the vector table which is placed at |
| 41 | + * a well-known location, concretely the very beginning of flash, 0x08000000. The linker script places the .vectors |
| 42 | + * section as the very first section into the flash to satisfy this. See Startup.c for the concrete content of the |
| 43 | + * vector table, and how the initial SP and PC are set up. |
| 44 | + * |
| 45 | + * - The initial startup code (ResetISR in Startup.c) only does one setup step (enabling the FPU) before performing the |
| 46 | + * reverse relocation of the data segment. The runtime back-relocation is simply a memcpy from __flash_data_start back |
| 47 | + * into __data_start (in the SRAM region). |
| 48 | + * |
| 49 | + * - During this and before this (e.g. when doing the FPU enablement), read-write globals cannot be used. Reading |
| 50 | + * a read-write global won't read the correct initial value of that global. |
| 51 | + * - That's why the ResetISR code is written as attribute((naked)) asm implementation. The implementation is also |
| 52 | + * very simple and it's easy to see that it indeed does not touch any globals. |
| 53 | + * - We expect that the implementation of memcpy is also not accessing any globals. This is a reasonable expectation |
| 54 | + * on any embedded-friendly memcpy implementation. |
| 55 | + * |
| 56 | + * - After that, the normal runtime memory layout is matched, and the application continues to initialize itself and |
| 57 | + * run. |
| 58 | + */ |
| 59 | + |
1 | 60 | MEMORY
|
2 | 61 | {
|
3 | 62 | flash (rx) : ORIGIN = 0x08000000, LENGTH = 1024K /* end: 0x08100000 */
|
|
0 commit comments