Part 1
요약·해설
MCUboot build·flash flow와 production key 주의, imgtool Kconfig, sysbuild·Zephyr property signing script override, rimage wrapper와 west config argument 전달을 설명합니다.
imgtool · signed image · chain-load
sysbuild · property · script
west config · shlex · extra-args
Part 2
접을 수 있는 영어 원문 전체
영어 원문 전체 펼치기
061EB3B41D09A02A3128F821EA30BD83FDDB2C06A24F408E75F56C96247899FB
.. _west-sign:
Signing Binaries
################
The ``west sign`` :ref:`extension <west-extensions>` command can be used to
sign a Zephyr application binary for consumption by a bootloader using an
external tool. In some configurations, ``west sign`` is also used to invoke
an external, post-processing tool that "stitches" the final components of
the image together. Run ``west sign -h`` for command line help.
MCUboot / imgtool
*****************
The Zephyr build system has special support for signing binaries for use with
the `MCUboot`_ bootloader using the `imgtool`_ program provided by its
developers. You can both build and sign this type of application binary in one
step by setting some Kconfig options. If you do, ``west flash`` will use the
signed binaries.
If you use this feature, you don't need to run ``west sign`` yourself; the
build system will do it for you.
Here is an example workflow, which builds and flashes MCUboot, as well as the
:ref:`hello_world` application for chain-loading by MCUboot. Run these commands
from the :file:`zephyrproject` workspace you created in the
:ref:`getting_started`.
.. code-block:: console
west build -b YOUR_BOARD bootloader/mcuboot/boot/zephyr -d build-mcuboot
west build -b YOUR_BOARD zephyr/samples/hello_world -d build-hello-signed -- \
-DCONFIG_BOOTLOADER_MCUBOOT=y \
-DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE=\"bootloader/mcuboot/root-rsa-2048.pem\"
west flash -d build-mcuboot
west flash -d build-hello-signed
Notes on the above commands:
- ``YOUR_BOARD`` should be changed to match your board
- The ``CONFIG_MCUBOOT_SIGNATURE_KEY_FILE`` value is the insecure default
provided and used by MCUboot for development and testing
- You can change the ``hello_world`` application directory to any other
application that can be loaded by MCUboot, such as the :zephyr:code-sample:`smp-svr` sample.
For more information on these and other related configuration options, see:
- :kconfig:option:`CONFIG_BOOTLOADER_MCUBOOT`: build the application for loading by
MCUboot
- :kconfig:option:`CONFIG_MCUBOOT_SIGNATURE_KEY_FILE`: the key file to use with ``west
sign``. If you have your own key, change this appropriately
- :kconfig:option:`CONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS`: optional additional command line
arguments for ``imgtool``
- :kconfig:option:`CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE`: also generate a confirmed
image, which may be more useful for flashing in production environments than
the OTA-able default image
- On Windows, if you get "Access denied" issues, the recommended fix is
to run ``pip3 install imgtool``, then retry with a pristine build directory.
If your ``west flash`` :ref:`runner <west-runner>` uses an image format
supported by imgtool, you should see something like this on your device's
serial console when you run ``west flash -d build-mcuboot``:
.. code-block:: none
*** Booting Zephyr OS build zephyr-v2.3.0-2310-gcebac69c8ae1 ***
[00:00:00.004,669] <inf> mcuboot: Starting bootloader
[00:00:00.011,169] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.021,636] <inf> mcuboot: Boot source: none
[00:00:00.027,313] <wrn> mcuboot: Failed reading image headers; Image=0
[00:00:00.035,064] <err> mcuboot: Unable to find bootable image
Then, you should see something like this when you run ``west flash -d
build-hello-signed``:
.. code-block:: none
*** Booting Zephyr OS build zephyr-v2.3.0-2310-gcebac69c8ae1 ***
[00:00:00.004,669] <inf> mcuboot: Starting bootloader
[00:00:00.011,169] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.021,636] <inf> mcuboot: Boot source: none
[00:00:00.027,374] <inf> mcuboot: Swap type: none
[00:00:00.115,142] <inf> mcuboot: Bootloader chainload address offset: 0xc000
[00:00:00.123,168] <inf> mcuboot: Jumping to the first image slot
*** Booting Zephyr OS build zephyr-v2.3.0-2310-gcebac69c8ae1 ***
Hello World! nrf52840dk_nrf52840
Whether ``west flash`` supports this feature depends on your runner. The
``nrfjprog`` and ``pyocd`` runners work with the above flow. If your runner
does not support this flow and you would like it to, please send a patch or
file an issue for adding support.
.. _west-extending-signing:
Extending signing externally
****************************
The signing script used when running ``west flash`` can be extended or replaced
to change features or introduce different signing mechanisms. By default with
MCUboot enabled, signing is setup by the :file:`cmake/mcuboot.cmake` file in
Zephyr which adds extra post build commands for generating the signed images.
The file used for signing can be replaced from a sysbuild scope (if being used)
or from a zephyr/zephyr module scope, the priority of which is:
* Sysbuild
* Zephyr property
* Default MCUboot script (if enabled)
From sysbuild, ``-D<target>_SIGNING_SCRIPT`` can be used to set a signing script
for a specific image or ``-DSIGNING_SCRIPT`` can be used to set a signing script
for all images, for example:
.. code-block:: console
west build -b <board> <application> -DSIGNING_SCRIPT=<file>
The zephyr property method is achieved by adjusting the ``SIGNING_SCRIPT`` property
on the `zephyr_property_target`, ideally from by a module by using:
.. code-block:: cmake
if(CONFIG_BOOTLOADER_MCUBOOT)
set_target_properties(zephyr_property_target PROPERTIES SIGNING_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/custom_signing.cmake)
endif()
This will include the custom signing CMake file instead of the default Zephyr
one when projects are built with MCUboot signing support enabled. The base
Zephyr MCUboot signing file can be used as a reference for creating a new
signing system or extending the default behaviour.
.. _MCUboot:
https://mcuboot.com/
.. _imgtool:
https://pypi.org/project/imgtool/
rimage
******
rimage configuration uses a different approach that does not rely on Kconfig or CMake
but on :ref:`west config<west-config>` instead, similar to
:ref:`west-building-cmake-config`.
Signing involves a number of "wrapper" scripts stacked on top of each other: ``west
flash`` invokes ``west build`` which invokes ``cmake`` and ``ninja`` which invokes
``west sign`` which invokes ``imgtool`` or `rimage`_. As long as the signing
parameters desired are the default ones and fairly static, these indirections are
not a problem. On the other hand, passing ``imgtool`` or ``rimage`` options through
all these layers can causes issues typical when the layers don't abstract
anything. First, this usually requires boilerplate code in each layer. Quoting
whitespace or other special characters through all the wrappers can be
difficult. Reproducing a lower ``west sign`` command to debug some build-time issue
can be very time-consuming: it requires at least enabling and searching verbose
build logs to find which exact options were used. Copying these options from the
build logs can be unreliable: it may produce different results because of subtle
environment differences. Last and worst: new signing feature and options are
impossible to use until more boilerplate code has been added in each layer.
To avoid these issues, ``rimage`` parameters can bet set in ``west config``
instead. Here's a ``workspace/.west/config`` example:
.. code-block:: ini
[sign]
# Not needed when invoked from CMake
tool = rimage
[rimage]
# Quoting is optional and works like in Unix shells
# Not needed when rimage can be found in the default PATH
path = "/home/me/zworkspace/build-rimage/rimage"
# Not needed when using the default development key
extra-args = -i 4 -k 'keys/key argument with space.pem'
In order to support quoting, values are parsed by Python's ``shlex.split()`` like in
:ref:`west-building-cmake-args`.
The ``extra-args`` are passed directly to the ``rimage`` command. The example
above has the same effect as appending them on command line after ``--`` like this:
``west sign --tool rimage -- -i 4 -k 'keys/key argument with space.pem'``. In case
both are used, the command-line arguments go last.
.. _rimage:
https://github.com/thesofproject/rimage
Part 3
한국어 전문 번역
Binary signing
west sign extension command는 외부 도구를 이용해 Zephyr application binary에 서명하여 bootloader가 사용할 수 있게 합니다. 일부 구성에서는 최종 image component를 하나로 "stitch"하는 외부 post-processing tool도 west sign으로 실행합니다. Command-line 도움말은 west sign -h로 확인합니다.
MCUboot와 imgtool
Zephyr build system은 MCUboot bootloader와 개발자가 제공하는 imgtool을 이용한 binary signing을 특별히 지원합니다. Kconfig option을 설정하면 application을 build하고 signing하는 과정을 한 번에 수행하며 west flash도 signed binary를 사용합니다.
이 기능을 사용하면 west sign을 직접 실행할 필요가 없습니다. Build system이 대신 실행합니다.
다음 workflow는 시작 안내에서 만든 zephyrproject workspace에서 MCUboot와 MCUboot가 chain-load할 hello_world application을 각각 build하고 flash합니다.
west build -b YOUR_BOARD bootloader/mcuboot/boot/zephyr -d build-mcuboot
west build -b YOUR_BOARD zephyr/samples/hello_world -d build-hello-signed -- \
-DCONFIG_BOOTLOADER_MCUBOOT=y \
-DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE=\"bootloader/mcuboot/root-rsa-2048.pem\"
west flash -d build-mcuboot
west flash -d build-hello-signed위 command에서 확인할 사항:
YOUR_BOARD를 실제 board 이름으로 바꿉니다.CONFIG_MCUBOOT_SIGNATURE_KEY_FILE에 지정된root-rsa-2048.pem은 MCUboot가 개발·test용으로 제공하는 안전하지 않은 기본 key입니다.hello_worlddirectory는 MCUboot가 load할 수 있는 다른 application이나smp-svrsample로 바꿀 수 있습니다.
관련 configuration option:
CONFIG_BOOTLOADER_MCUBOOT: application을 MCUboot가 load할 형식으로 build합니다.CONFIG_MCUBOOT_SIGNATURE_KEY_FILE:west sign이 사용할 key file입니다. 자체 key가 있으면 이 값을 바꿉니다.CONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS: imgtool에 전달할 선택적인 추가 command-line argument입니다.CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE: OTA 가능한 기본 image뿐 아니라 confirmed image도 생성합니다. Confirmed image는 production 환경에서 직접 flash할 때 더 유용할 수 있습니다.- Windows에서 "Access denied"가 발생하면
pip3 install imgtool을 실행한 뒤 pristine build directory로 다시 build하는 것이 권장됩니다.
west flash runner가 imgtool이 지원하는 image format을 사용한다면 먼저 west flash -d build-mcuboot을 실행했을 때 serial console에서 다음과 같이 아직 bootable image가 없다는 출력을 볼 수 있습니다.
*** Booting Zephyr OS build zephyr-v2.3.0-2310-gcebac69c8ae1 ***
[00:00:00.004,669] <inf> mcuboot: Starting bootloader
[00:00:00.011,169] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.021,636] <inf> mcuboot: Boot source: none
[00:00:00.027,313] <wrn> mcuboot: Failed reading image headers; Image=0
[00:00:00.035,064] <err> mcuboot: Unable to find bootable image그다음 west flash -d build-hello-signed을 실행하면 signed image를 찾아 첫 image slot으로 jump한 뒤 application이 실행되는 다음과 같은 출력을 볼 수 있습니다.
*** Booting Zephyr OS build zephyr-v2.3.0-2310-gcebac69c8ae1 ***
[00:00:00.004,669] <inf> mcuboot: Starting bootloader
[00:00:00.011,169] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.021,636] <inf> mcuboot: Boot source: none
[00:00:00.027,374] <inf> mcuboot: Swap type: none
[00:00:00.115,142] <inf> mcuboot: Bootloader chainload address offset: 0xc000
[00:00:00.123,168] <inf> mcuboot: Jumping to the first image slot
*** Booting Zephyr OS build zephyr-v2.3.0-2310-gcebac69c8ae1 ***
Hello World! nrf52840dk_nrf52840이 flow의 지원 여부는 flash runner에 달려 있습니다. nrfjprog와 pyocd runner는 지원합니다. 다른 runner에도 필요하다면 patch를 보내거나 지원 issue를 등록합니다.
외부 signing 확장
west flash에서 쓰는 signing script는 기능을 바꾸거나 다른 signing mechanism을 넣도록 확장·교체할 수 있습니다. MCUboot가 enabled이면 기본적으로 Zephyr의 cmake/mcuboot.cmake가 post-build command를 추가해 signed image를 만듭니다.
Signing file은 sysbuild scope 또는 Zephyr/module scope에서 바꿀 수 있으며 우선순위는 다음과 같습니다.
- Sysbuild 설정
- Zephyr property
- 기본 MCUboot script(MCUboot가 enabled인 경우)
Sysbuild에서는 특정 image에 -D<target>_SIGNING_SCRIPT를, 모든 image에 -DSIGNING_SCRIPT를 사용합니다.
west build -b <board> <application> -DSIGNING_SCRIPT=<file>Zephyr property 방식은 되도록 module에서 zephyr_property_target의 SIGNING_SCRIPT property를 바꿉니다.
if(CONFIG_BOOTLOADER_MCUBOOT)
set_target_properties(zephyr_property_target PROPERTIES SIGNING_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/custom_signing.cmake)
endif()MCUboot signing support가 enabled인 project를 build하면 기본 Zephyr signing CMake file 대신 custom_signing.cmake가 include됩니다. Zephyr의 기본 MCUboot signing file은 새 signing system을 만들거나 기본 동작을 확장할 때 참고 구현으로 사용할 수 있습니다.
rimage
rimage configuration은 Kconfig나 CMake가 아니라 west config를 사용합니다. 이는 영구 CMake argument를 config에 저장하는 방식과 비슷합니다.
Signing은 wrapper가 여러 겹으로 쌓입니다. west flash가 west build를, build가 cmake와 ninja를, 그것들이 west sign을, 마지막으로 sign이 imgtool 또는 rimage를 실행합니다.
원하는 parameter가 기본값이고 거의 변하지 않으면 이 간접 계층은 문제가 되지 않습니다. 하지만 imgtool·rimage option을 모든 계층을 통과시킬 때는 다음 문제가 생깁니다.
- 각 wrapper layer에 같은 option 전달 boilerplate가 필요합니다.
- 공백이나 특수 문자를 여러 wrapper에서 정확히 quote하기 어렵습니다.
west sign단계의 build-time 문제를 재현하려면 verbose build log를 켜고 실제 option을 찾아야 하므로 시간이 오래 걸립니다.- Build log에서 복사한 option도 미묘한 environment 차이 때문에 같은 결과를 내지 않을 수 있습니다.
- 새 signing 기능과 option은 모든 layer에 전달 code가 추가되기 전까지 사용할 수 없습니다.
이 문제를 피하려면 rimage parameter를 west config에 저장합니다. 다음은 workspace/.west/config 예입니다.
[sign]
# Not needed when invoked from CMake
tool = rimage
[rimage]
# Quoting is optional and works like in Unix shells
# Not needed when rimage can be found in the default PATH
path = "/home/me/zworkspace/build-rimage/rimage"
# Not needed when using the default development key
extra-args = -i 4 -k 'keys/key argument with space.pem'Quote를 지원하기 위해 값은 영구 CMake argument와 마찬가지로 Python shlex.split() 규칙으로 parsing합니다.
extra-args는 rimage command에 직접 전달됩니다. 예제 config는 west sign --tool rimage -- -i 4 -k 'keys/key argument with space.pem'처럼 -- 뒤에 option을 붙인 것과 같습니다. Config와 command line을 모두 사용하면 command-line argument가 마지막에 놓이므로 뒤쪽 option의 우선순위를 가집니다.
Source
출처
영어 원문에는 문단, 문서 지시문, 표, 코드, 코드 심벌, 경로를 그대로 보존했습니다.