summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntonin Godard <antonin.godard@bootlin.com>2025-02-17 15:50:25 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2025-02-26 14:49:28 +0000
commitdcfbb14ad38aa31eab9f51c4af21b6f85667963c (patch)
tree806b3c45782deb3a6f708b5123f7657cf1117db6
parent705966c54623b85775ba540acbd6941c91e23e40 (diff)
downloadpoky-dcfbb14ad38aa31eab9f51c4af21b6f85667963c.tar.gz
dev-manual/multiconfig: add suggested best practices and baremetal sections
After the suggestions from Mark Hatle on the list (https://lists.yoctoproject.org/g/docs/topic/110487932), add two sections to the multiconfig doc: - Suggested best practices: suggestion for better design of multiconfig builds. - Common use case: baremetal build. This section applies the guidelines from the first sections and apply it to a real-life example of how to use multiconfig. This one to build some baremetal firmware alongside a regular Linux build. Suggested-by: Mark Hatle <mark.hatle@kernel.crashing.org> Reviewed-by: Quentin Schulz <quentin.schulz@cherry.de> (From yocto-docs rev: 36fb1e9e5099aa0d858d5478530143e9bac39588) Signed-off-by: Antonin Godard <antonin.godard@bootlin.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--documentation/dev-manual/multiconfig.rst136
1 files changed, 136 insertions, 0 deletions
diff --git a/documentation/dev-manual/multiconfig.rst b/documentation/dev-manual/multiconfig.rst
index 8371cf0e46..71fe542efb 100644
--- a/documentation/dev-manual/multiconfig.rst
+++ b/documentation/dev-manual/multiconfig.rst
@@ -174,3 +174,139 @@ and have separate configuration files, BitBake places the artifacts for
174each build in the respective temporary build directories (i.e. 174each build in the respective temporary build directories (i.e.
175:term:`TMPDIR`). 175:term:`TMPDIR`).
176 176
177Suggested best practices
178========================
179
180- :term:`TMPDIR` (other than the default set in bitbake.conf) is only set in
181 ``local.conf`` by the user. This means that we should **not** manipulate
182 :term:`TMPDIR` in any way within the Machine or Distro :term:`configuration
183 file`.
184
185- A multiconfig should specify a :term:`TMPDIR`, and should specify it by
186 appending the multiconfig name with :term:`BB_CURRENT_MC`.
187
188- Recipes that are used to transfer the output from a multiconfig build to
189 another should use ``do_task[mcdepends]`` to trigger the build of the
190 component, and then transfer the item to the current configuration in
191 :ref:`ref-tasks-install` and :ref:`ref-tasks-deploy`, assuming the value of
192 the deployed item based on :term:`TMPDIR`.
193
194 The :ref:`ref-tasks-install` and :ref:`ref-tasks-deploy` tasks should look
195 like this::
196
197 do_install() {
198 install -m 0644 ${TMPDIR}-<multiconfig>/tmp/deploy/images/<machine>/somefile ${D}/some/path
199 }
200
201 do_deploy() {
202 install -m 0644 ${TMPDIR}-<multiconfig>/tmp/deploy/images/<machine>/somefile ${DEPLOYDIR}/somefile
203 }
204
205 In the example above:
206
207 - ``<multiconfig>`` is the multiconfig name as set by the multiconfig
208 :term:`configuration file` (see the :ref:`dev-manual/multiconfig:Setting
209 Up and Running a Multiple Configuration Build` section above).
210
211 - ``<machine>`` must be the :term:`MACHINE` for which ``somefile`` was built
212 and deployed. This value may differ from the current :term:`MACHINE` if
213 the multiconfig :term:`configuration file` overrides it.
214
215- Firmware recipes can set the :term:`INHIBIT_DEFAULT_DEPS` variable to ``1``
216 if they don't rely on default dependencies such as the standard C library.
217
218Common use case: building baremetal firmware alongside a Linux build
219====================================================================
220
221A common use case for multiconfig is to use the default configuration as the
222regular Linux build, while one or more multiconfigs can be used to build special
223components, such as baremetal firmware. It would also apply to a scenario where
224a microcontroller, for example, is companion to a main processor where Linux is
225running. This section details how one can achieve these kinds of scenarios with
226a multiconfig build.
227
228Adding a multiconfig configuration file and recipe for a baremetal firmware
229---------------------------------------------------------------------------
230
231As described in :ref:`dev-manual/multiconfig:Setting Up and Running a Multiple
232Configuration Build`, each multiconfig will require a separate
233:term:`Configuration File`. In addition, we will define a separate
234:term:`TMPDIR` for our baremetal firmware build configuration.
235
236For example, we will define a new ``conf/multiconfig/baremetal-firmware.conf``
237as follows::
238
239 TMPDIR .= "-${BB_CURRENT_MC}"
240 TCLIBC = "newlib"
241
242The ``baremetal-firmware.conf`` file configures a separate :term:`TMPDIR` for
243holding binaries compiled with the `newlib <https://sourceware.org/newlib/>`__
244toolchain (see :term:`TCLIBC`).
245
246.. note::
247
248 Here, the default :term:`MACHINE` is not overridden by the multiconfig
249 configuration file. As a consequence, the architecture of the built baremetal
250 binaries will be the same. In other cases, where the firmware runs on a
251 completely different architecture, the :term:`MACHINE` must be overridden.
252
253We then create a recipe ``my-firmware.bb`` that defines how the baremetal
254firmware is built. The recipe should contain enough information for the
255:term:`OpenEmbedded build system` to properly compile the firmware with our
256toolchain. The building tasks may vary depending on the nature of the firmware.
257However, the recipe should define a :ref:`ref-classes-deploy` task that deploys
258the output into the :term:`DEPLOYDIR` directory. We will consider in the
259following that the file is named ``my-firmware.elf``.
260
261Building the firmware
262---------------------
263
264The firmware can be built with BitBake with the following command::
265
266 $ bitbake mc:baremetal-firmware:my-firmware
267
268However, we would prefer for ``my-firmware`` to be automatically built when
269triggering a normal Linux build.
270
271Using a ``mcdepend``, a recipe belonging to the Linux build can trigger the
272build of ``my-firmware``. For example, let's consider that our Linux build needs
273to assemble a "special" firmware that uses the output of our ``my-firmware``
274recipe - let's call it ``my-parent-firmware.bb``. Then, we should specify this
275dependency in ``my-parent-firmware.bb`` with::
276
277 do_compile[mcdepends] = "mc::baremetal-firmware:my-firmware:do_deploy"
278
279The above will ensure that when the :ref:`ref-tasks-compile` task of
280``my-parent-firmware`` is triggered, the :ref:`ref-tasks-deploy` task of
281``my-firmware`` will already have run successfully.
282
283Using the output of ``my-firmware``
284-----------------------------------
285
286After ``my-firmware`` recipe has deployed ``my-firmware.elf``, we need to use
287the output in some way. We can make a series of assumptions, based on the
288default Yocto Project variables in order to get the binary for packaging.
289
290First, we can set the following in ``my-parent-firmware.bb``::
291
292 FIRMWARE_FILE ??= "${TMPDIR}-baremetal-firmware/deploy/images/<machine>/my-firmware.elf"
293 FIRMWARE_FILE[vardepsexclude] += "TMPDIR"
294
295The first assignment stores the value of the path to the firmware built and
296deployed by the ``my-firmware.bb`` recipe. The second assignment excludes the
297:term:`TMPDIR` variable from being part of ``FIRMWARE_FILE``'s dependencies ---
298meaning that changing the value of :term:`TMPDIR` (for example, changing the
299host on which the firmware is built) will not invalidate the :ref:`shared state
300cache <overview-manual/concepts:shared state cache>`.
301
302Additionally, ``<machine>`` should be replaced by the :term:`MACHINE` for which
303we are building in the baremetal-firmware context.
304
305We can then add a :ref:`ref-tasks-install` task to ``my-parent-firmware``::
306
307 do_install() {
308 install -Dm 0644 ${FIRMWARE_FILE} ${D}/lib/firmware/my-firmware.elf
309 }
310
311Doing the above will allow the firmware binary to be transferred and packaged
312into the Linux context and rootfs.