linker-script-generation.rst 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. Linker Script Generation
  2. ========================
  3. :link_to_translation:`zh_CN:[中文]`
  4. Overview
  5. --------
  6. There are several :ref:`memory regions<memory-layout>` where code and data can be placed. Usually, code and read-only data are placed in flash regions,
  7. writable data in RAM, etc. A common action is changing where code/data are mapped by default, say placing critical code/rodata in RAM for performance
  8. reasons or placing code/data/rodata in RTC memory for use in a wake stub or the ULP coprocessor.
  9. IDF provides the ability for defining these placements at the component level using the linker script generation mechanism. The component presents
  10. how it would like to map the input sections of its object files (or even functions/data) through :ref:`linker fragment files<ldgen-fragment-files>`. During app build,
  11. the linker fragment files are collected, parsed and processed; and the :ref:`linker script template<ldgen-script-templates>` is augmented with
  12. information generated from the fragment files to produce the final linker script. This linker script is then used for the linking
  13. the final app binary.
  14. Quick Start
  15. ------------
  16. This section presents a guide for quickly placing code/data to RAM and RTC memory; as well as demonstrating how to make these placements
  17. dependent on project configuration values. In a true quick start fashion, this section glosses over terms and concepts that will be discussed
  18. at a later part of the document. However, whenever it does so, it provides a link to the relevant section on the first mention.
  19. .. _ldgen-add-fragment-file :
  20. Preparation
  21. ^^^^^^^^^^^
  22. Make
  23. """"
  24. Create a linker fragment file inside the component directory, which is just a text file with a .lf extension. In order for the build system to collect your fragment file,
  25. add an entry to it from the component, set the variable ``COMPONENT_ADD_LDFRAGMENTS`` to your linker file/s before the ``register_component`` call.
  26. .. code-block:: make
  27. # file paths relative to component Makefile
  28. COMPONENT_ADD_LDFRAGMENTS += path/to/linker_fragment_file.lf
  29. CMake
  30. """""
  31. For CMake set the variable ``COMPONENT_ADD_LDFRAGMENTS`` to your linker file/s before the ``register_component`` call.
  32. .. code-block:: cmake
  33. # file paths relative to CMakeLists.txt
  34. set(COMPONENT_ADD_LDFRAGMENTS "path/to/linker_fragment_file.lf" "path/to/another_linker_fragment_file.lf")
  35. register_component()
  36. It is also possible to specify fragment files from the project CMakeLists.txt or component project_include.cmake using the function `ldgen_add_fragment_files`::
  37. ldgen_add_fragment_files(target files ...)
  38. Specifying placements
  39. ^^^^^^^^^^^^^^^^^^^^^
  40. This mechanism allows specifying placement of the following entities:
  41. - one or multiple object files within the component
  42. - one or multiple function/variable using their names
  43. - the entire component library
  44. For the following text, suppose we have the following:
  45. - a component named ``component`` that is archived as library ``libcomponent.a`` during build
  46. - three object files archived under the library, ``object1.o``, ``object2.o`` and ``object3.o``
  47. - under ``object1.o``, the function ``function1`` is defined; under ``object2.o``, the function ``function2`` is defined
  48. - there exist configuration ``PERFORMANCE_MODE`` and ``PERFORMANCE_LEVEL`` in one of the IDF KConfig files, with the set value indicated by entries ``CONFIG_PERFORMANCE_MODE`` and ``CONFIG_PERFORMANCE_LEVEL`` in the project sdkconfig
  49. In the created linker fragment file, we write:
  50. .. code-block:: none
  51. [mapping]
  52. archive: libcomponent.a
  53. entries:
  54. This creates an empty :ref:`mapping fragment<ldgen-mapping-fragment>`, which doesn't do anything yet. During linking the :ref:`default placements<ldgen-default-placements>`
  55. will still be used for ``libcomponent.a``, unless the ``entries`` key is populated.
  56. .. _ldgen-placing-object-files :
  57. Placing object files
  58. """"""""""""""""""""
  59. Suppose the entirety of ``object1.o`` is performance-critical, so it is desirable to place it in RAM. On the other hand, suppose all of ``object2.o`` contains things to be executed coming out of deep sleep, so it needs to be put under RTC memory. We can write:
  60. .. code-block:: none
  61. [mapping]
  62. archive: libcomponent.a
  63. entries:
  64. object1 (noflash) # places all code / read-only data under IRAM/ DRAM
  65. object2 (rtc) # places all code/ data and read-only data under RTC fast memory/ RTC slow memory
  66. What happens to ``object3.o``? Since it is not specified, default placements are used for ``object3.o``.
  67. Placing functions/data using their names
  68. """"""""""""""""""""""""""""""""""""""""
  69. Continuing our example, suppose that among functions defined under ``object1.o``, only ``function1`` is performance-critical; and under ``object2.o``,
  70. only ``function2`` needs to execute after the chip comes out of deep sleep. This could be accomplished by writing:
  71. .. code-block:: none
  72. [mapping]
  73. archive: libcomponent.a
  74. entries:
  75. object1:function1 (noflash)
  76. object2:function2 (rtc)
  77. The default placements are used for the rest of the functions in ``object1.o`` and ``object2.o`` and the entire ``object3.o``. Something similar
  78. can be achieved for placing data by writing the variable name instead of the function name after ``:``.
  79. .. warning::
  80. There are :ref:`limitations<ldgen-type1-limitations>` in placing code/data using their symbol names. In order to ensure proper placements, an alternative would be to group
  81. relevant code and data into source files, and :ref:`use object file placement<ldgen-placing-object-files>`.
  82. Placing entire component
  83. """"""""""""""""""""""""
  84. In this example, suppose that the entire component needs to be placed in RAM. This can be written as:
  85. .. code-block:: none
  86. [mapping]
  87. archive: libcomponent.a
  88. entries:
  89. * (noflash)
  90. Similarly, this places the entire component in RTC memory:
  91. .. code-block:: none
  92. [mapping]
  93. archive: libcomponent.a
  94. entries:
  95. * (rtc)
  96. Configuration-dependent placements
  97. """"""""""""""""""""""""""""""""""
  98. Suppose that the entire component library should only be placed when ``CONFIG_PERFORMANCE_MODE == y`` in the sdkconfig. This could be written as:
  99. .. code-block:: none
  100. [mapping]
  101. archive: libcomponent.a
  102. entries:
  103. : PERFORMANCE_MODE = y
  104. * (noflash)
  105. In pseudocode, this translates to:
  106. .. code-block:: none
  107. if PERFORMANCE_MODE = y
  108. place entire libcomponent.a in RAM
  109. else
  110. use default placements
  111. It is also possible to have multiple conditions to test. Suppose the following requirements: when ``CONFIG_PERFORMANCE_LEVEL == 1``, only ``object1.o`` is put in RAM;
  112. when ``CONFIG_PERFORMANCE_LEVEL == 2``, ``object1.o`` and ``object2.o``; and when ``CONFIG_PERFORMANCE_LEVEL == 3`` all object files under the archive
  113. are to be put into RAM. When these three are false however, put entire library in RTC memory. This scenario is a bit contrived, but,
  114. it can be written as:
  115. .. code-block:: none
  116. [mapping]
  117. archive: libcomponent.a
  118. entries:
  119. : PERFORMANCE_LEVEL = 3
  120. * (noflash)
  121. : PERFORMANCE_LEVEL = 2
  122. object1 (noflash)
  123. object2 (noflash)
  124. : PERFORMANCE_LEVEL = 1
  125. object1 (noflash)
  126. : default
  127. * (rtc)
  128. Which reads:
  129. .. code-block:: none
  130. if CONFIG_PERFORMANCE_LEVEL == 3
  131. place entire libcomponent.a in RAM
  132. else if CONFIG_PERFORMANCE_LEVEL == 2
  133. only place object1.o and object2.o in RAM
  134. else if CONFIG_PERFORMANCE_LEVEL == 1
  135. only place object1.o in RAM
  136. else
  137. place entire libcomponent.a in RTC memory
  138. The conditions test :ref:`support other operations<ldgen-condition-entries>`.
  139. .. _ldgen-default-placements:
  140. The 'default' placements
  141. ^^^^^^^^^^^^^^^^^^^^^^^^
  142. Up until this point, the term 'default placements' has been mentioned as fallback placements for when the
  143. placement rules ``rtc`` and ``noflash`` are not specified. The tokens ``noflash`` or ``rtc`` are not merely keywords known by the mechanism, but are actually
  144. objects called :ref:`scheme fragments<ldgen-scheme-fragment>` that are specified by the user. Due to the commonness of these placement use cases,
  145. they are pre-defined in IDF.
  146. Similarly, there exists a ``default`` scheme fragment which defines what the default placement rules should be, which is discussed :ref:`here<ldgen-default-scheme>`.
  147. .. note::
  148. For an example of an IDF component using this feature, see :component_file:`freertos/CMakeLists.txt`. The ``freertos`` component uses this
  149. mechanism to place all code, literal and rodata of all of its object files to the instruction RAM memory region for performance reasons.
  150. This marks the end of the quick start guide. The following text discusses this mechanism in a little bit more detail, such its components, essential concepts,
  151. the syntax, how it is integrated with the build system, etc. The following sections should be helpful in creating custom mappings or modifying default
  152. behavior.
  153. Components
  154. ----------
  155. .. _ldgen-fragment-files :
  156. Linker Fragment Files
  157. ^^^^^^^^^^^^^^^^^^^^^
  158. The fragment files contain objects called 'fragments'. These fragments contain pieces of information which, when put together, form
  159. placement rules that tell where to place sections of object files in the output binary.
  160. Another way of putting it is that processing linker fragment files aims to create the section placement rules inside GNU LD ``SECTIONS`` command.
  161. Where to collect and put these section placement rules is represented internally as a ``target`` token.
  162. The three types of fragments are discussed below.
  163. .. note::
  164. Fragments have a name property (except mapping fragments) and are known globally.
  165. Fragment naming follows C variable naming rules, i.e. case sensitive, must begin with a letter or underscore, alphanumeric/underscore after
  166. initial characters are allowed, no spaces/special characters. Each type of fragment has its own namespace. In cases where multiple fragments
  167. of the same type and name are encountered, an exception is thrown.
  168. .. _ldgen-sections-fragment :
  169. I. Sections
  170. """""""""""
  171. Sections fragments defines a list of object file sections that the GCC compiler emits. It may be a default section (e.g. ``.text``, ``.data``) or
  172. it may be user defined section through the ``__attribute__`` keyword.
  173. The use of an optional '+' indicates the inclusion of the section in the list, as well as sections that start with it. This is the preferred method over listing both explicitly.
  174. **Syntax**
  175. .. code-block:: none
  176. [sections:name]
  177. entries:
  178. .section+
  179. .section
  180. ...
  181. **Example**
  182. .. code-block:: none
  183. # Non-preferred
  184. [sections:text]
  185. entries:
  186. .text
  187. .text.*
  188. .literal
  189. .literal.*
  190. # Preferred, equivalent to the one above
  191. [sections:text]
  192. entries:
  193. .text+ # means .text and .text.*
  194. .literal+ # means .literal and .literal.*
  195. .. _ldgen-scheme-fragment :
  196. II. Scheme
  197. """"""""""
  198. Scheme fragments define what ``target`` a sections fragment is assigned to.
  199. **Syntax**
  200. .. code-block:: none
  201. [scheme:name]
  202. entries:
  203. sections -> target
  204. sections -> target
  205. ...
  206. **Example**
  207. .. code-block:: none
  208. [scheme:noflash]
  209. entries:
  210. text -> iram0_text # the entries under the sections fragment named text will go to iram0_text
  211. rodata -> dram0_data # the entries under the sections fragment named rodata will go to dram0_data
  212. .. _ldgen-default-scheme:
  213. **The** ``default`` **scheme**
  214. There exists a special scheme with the name ``default``. This scheme is special because catch-all placement rules are generated from
  215. its entries. This means that, if one of its entries is ``text -> flash_text``, the placement rule
  216. .. code-block:: none
  217. *(.literal .literal.* .text .text.*)
  218. will be generated for the target ``flash_text``.
  219. These catch-all rules then effectively serve as fallback rules for those whose mappings were not specified.
  220. .. note::
  221. The ``default scheme`` is defined in :component:`esp32/ld/esp32_fragments.lf`. The ``noflash`` and ``rtc`` scheme fragments which are
  222. built-in schemes referenced in the quick start guide are also defined in this file.
  223. .. _ldgen-mapping-fragment :
  224. III. Mapping
  225. """"""""""""
  226. Mapping fragments define what scheme fragment to use for mappable entities, i.e. object files, function names, variable names. There are two types of entries
  227. for this fragment: mapping entries and condition entries.
  228. .. note::
  229. Mapping fragments have no explicit name property. Internally, the name is constructed from the value of the archive entry.
  230. **Syntax**
  231. .. code-block:: none
  232. [mapping]
  233. archive: archive # output archive file name, as built (i.e. libxxx.a)
  234. entries:
  235. : condition # condition entry, non-default
  236. object:symbol (scheme) # mapping entry, Type I
  237. object (scheme) # mapping entry, Type II
  238. * (scheme) # mapping entry, Type III
  239. # optional separation/comments, for readability
  240. : default # condition entry, default
  241. * (scheme) # mapping entry, Type III
  242. .. _ldgen-mapping-entries :
  243. **Mapping Entries**
  244. There are three types of mapping entries:
  245. ``Type I``
  246. The object file name and symbol name are specified. The symbol name can be a function name or a variable name.
  247. ``Type II``
  248. Only the object file name is specified.
  249. ``Type III``
  250. ``*`` is specified, which is a short-hand for all the object files under the archive.
  251. To know what a mapping entry means, let us expand a ``Type II`` entry. Originally:
  252. .. code-block:: none
  253. object (scheme)
  254. Then expanding the scheme fragment from its entries definitions, we have:
  255. .. code-block:: none
  256. object (sections -> target,
  257. sections -> target,
  258. ...)
  259. Expanding the sections fragment with its entries definition:
  260. .. code-block:: none
  261. object (.section, # given this object file
  262. .section, # put its sections listed here at this
  263. ... -> target, # target
  264. .section,
  265. .section, # same should be done for these sections
  266. ... -> target,
  267. ...) # and so on
  268. .. _ldgen-type1-limitations :
  269. **On** ``Type I`` **Mapping Entries**
  270. ``Type I`` mapping entry is possible due to compiler flags ``-ffunction-sections`` and ``-ffdata-sections``. If the user opts to remove these flags, then
  271. the ``Type I`` mapping will not work. Furthermore, even if the user does not opt to compile without these flags, there are still limitations
  272. as the implementation is dependent on the emitted output sections.
  273. For example, with ``-ffunction-sections``, separate sections are emitted for each function; with section names predictably constructed i.e. ``.text.{func_name}``
  274. and ``.literal.{func_name}``. This is not the case for string literals within the function, as they go to pooled or generated section names.
  275. With ``-fdata-sections``, for global scope data the compiler predictably emits either ``.data.{var_name}``, ``.rodata.{var_name}`` or ``.bss.{var_name}``; and so ``Type I`` mapping entry works for these.
  276. However, this is not the case for static data declared in function scope, as the generated section name is a result of mangling the variable name with some other information.
  277. .. _ldgen-condition-entries :
  278. **Condition Entries**
  279. Condition entries enable the linker script generation to be configuration-aware. Depending on whether expressions involving configuration values
  280. are true or not, a particular set of mapping entries can be used. The evaluation uses ``eval_string`` from :idf_file:`tools/kconfig_new/kconfiglib.py` and adheres to its required syntax and limitations.
  281. All mapping entries defined after a condition entry until the next one or the end of the mapping fragment belongs to that condition entry. During processing
  282. conditions are tested sequentially, and the mapping entries under the first condition that evaluates to ``TRUE`` are used.
  283. A default condition can be defined (though every mapping contains an implicit, empty one), whose mapping entries get used in the event no conditions evaluates to ``TRUE``.
  284. **Example**
  285. .. code-block:: none
  286. [scheme:noflash]
  287. entries:
  288. text -> iram0_text
  289. rodata -> dram0_data
  290. [mapping:lwip]
  291. archive: liblwip.a
  292. entries:
  293. : LWIP_IRAM_OPTIMIZATION = y # if CONFIG_LWIP_IRAM_OPTIMIZATION is set to 'y' in sdkconfig
  294. ip4:ip4_route_src_hook (noflash) # map ip4.o:ip4_route_src_hook, ip4.o:ip4_route_src and
  295. ip4:ip4_route_src (noflash) # ip4.o:ip4_route using the noflash scheme, which puts
  296. ip4:ip4_route (noflash) # them in RAM
  297. : default # else no special mapping rules apply
  298. .. _ldgen-script-templates :
  299. Linker Script Template
  300. ^^^^^^^^^^^^^^^^^^^^^^
  301. The linker script template is the skeleton in which the generated placement rules are put into. It is an otherwise ordinary linker script, with a specific marker syntax
  302. that indicates where the generated placement rules are placed.
  303. **Syntax**
  304. To reference the placement rules collected under a ``target`` token, the following syntax is used:
  305. .. code-block:: none
  306. mapping[target]
  307. **Example**
  308. The example below is an excerpt from a possible linker script template. It defines an output section ``.iram0.text``, and inside is a marker referencing
  309. the target ``iram0_text``.
  310. .. code-block:: none
  311. .iram0.text :
  312. {
  313. /* Code marked as runnning out of IRAM */
  314. _iram_text_start = ABSOLUTE(.);
  315. /* Marker referencing iram0_text */
  316. mapping[iram0_text]
  317. _iram_text_end = ABSOLUTE(.);
  318. } > iram0_0_seg
  319. Suppose the generator collected the fragment definitions below:
  320. .. code-block:: none
  321. [sections:text]
  322. .text+
  323. .literal+
  324. [sections:iram]
  325. .iram1+
  326. [scheme:default]
  327. entries:
  328. text -> flash_text
  329. iram -> iram0_text
  330. [scheme:noflash]
  331. entries:
  332. text -> iram0_text
  333. [mapping:freertos]
  334. archive: libfreertos.a
  335. entries:
  336. * (noflash)
  337. Then the corresponding excerpt from the generated linker script will be as follows:
  338. .. code-block:: c
  339. .iram0.text :
  340. {
  341. /* Code marked as runnning out of IRAM */
  342. _iram_text_start = ABSOLUTE(.);
  343. /* Placement rules generated from the processed fragments, placed where the marker was in the template */
  344. *(.iram1 .iram1.*)
  345. *libfreertos.a:(.literal .text .literal.* .text.*)
  346. _iram_text_end = ABSOLUTE(.);
  347. } > iram0_0_seg
  348. ``*libfreertos.a:(.literal .text .literal.* .text.*)``
  349. Rule generated from the entry ``* (noflash)`` of the ``freertos`` mapping fragment. All ``text`` sections of all
  350. object files under the archive ``libfreertos.a`` will be collected under the target ``iram0_text`` (as per the ``noflash`` scheme)
  351. and placed wherever in the template ``iram0_text`` is referenced by a marker.
  352. ``*(.iram1 .iram1.*)``
  353. Rule generated from the default scheme entry ``iram -> iram0_text``. Since the default scheme specifies an ``iram -> iram0_text`` entry,
  354. it too is placed wherever ``iram0_text`` is referenced by a marker. Since it is a rule generated from the default scheme, it comes first
  355. among all other rules collected under the same target name.
  356. Integration with Build System
  357. -----------------------------
  358. The linker script generation occurs during application build, before the final output binary is linked. The tool that implements the mechanism
  359. lives under ``$(IDF_PATH)/tools/ldgen``.
  360. Linker Script Template
  361. ^^^^^^^^^^^^^^^^^^^^^^
  362. Currently, the linker script template used is :component:`esp32/ld/esp32.project.ld.in`, and is used only for the app build. The generated output script is
  363. put under the build directory of the same component. Modifying this linker script template triggers a re-link of the app binary.
  364. Linker Fragment File
  365. ^^^^^^^^^^^^^^^^^^^^
  366. Any component can add a fragment file to the build. In order to add a fragment file to process, set COMPONENT_ADD_LDFRAGMENTS or use the function ``ldgen_add_fragment_files`` (CMake only) as mentioned :ref:`here <ldgen-add-fragment-file>`.
  367. Modifying any fragment file presented to the build system triggers a re-link of the app binary.