blob: 29c46ec56450386079398999f5baecb6f3720ea6 [file] [log] [blame] [view]
Carles Cufiecc34bb2018-01-22 18:02:46 +01001# Building and using MCUboot with Zephyr
2
3MCUboot began its life as the bootloader for Mynewt. It has since
4acquired the ability to be used as a bootloader for Zephyr as well.
5There are some pretty significant differences in how apps are built
6for Zephyr, and these are documented here.
7
Fabio Utzig4dce6aa2018-02-12 15:31:32 -02008Please see the [design document](design.md) for documentation on the design
9and operation of the bootloader itself. This functionality should be the same
10on all supported RTOSs.
Carles Cufiecc34bb2018-01-22 18:02:46 +010011
12The first step required for Zephyr is making sure your board has flash
13partitions defined in its device tree. These partitions are:
14
15- `boot_partition`: for MCUboot itself
Andrzej Puzdrowski75001562022-10-05 17:45:29 +020016- `slot0_partition`: the primary slot of Image 0
17- `slot1_partition`: the secondary slot of Image 0
Jamie McCrae0b7b7ae2022-12-19 11:43:54 +000018
19It is not recommended to use the swap-using-scratch algorithm of MCUboot, but
20if this operating mode is desired then the following flash partition is also
21needed (see end of this help file for details on creating a scratch partition
22and how to use the swap-using-scratch algorithm):
23
Carles Cufiecc34bb2018-01-22 18:02:46 +010024- `scratch_partition`: the scratch slot
25
26Currently, the two image slots must be contiguous. If you are running
27MCUboot as your stage 1 bootloader, `boot_partition` must be configured
David Vinczeba3bd602019-06-17 16:01:43 +020028so your SoC runs it out of reset. If there are multiple updateable images
29then the corresponding primary and secondary partitions must be defined for
Andrzej Puzdrowski75001562022-10-05 17:45:29 +020030the rest of the images too (for example, `slot2_partition` and
31`slot3_partition` for Image 1).
Carles Cufiecc34bb2018-01-22 18:02:46 +010032
33The flash partitions are typically defined in the Zephyr boards folder, in a
34file named `boards/<arch>/<board>/<board>.dts`. An example `.dts` file with
35flash partitions defined is the frdm_k64f's in
Andrzej Puzdrowski75001562022-10-05 17:45:29 +020036`boards/arm/frdm_k64f/frdm_k64f.dts`. Make sure the DT node labels in your board's
Carles Cufiecc34bb2018-01-22 18:02:46 +010037`.dts` file match the ones used there.
38
Francesco Servidio5bc98322021-11-03 13:19:22 +010039## Installing requirements and dependencies
Piotr Mienkowski8a474ff2018-08-07 21:31:33 +020040
Francesco Servidio4ff0c182021-10-20 15:27:16 +020041Install additional packages required for development with MCUboot:
Piotr Mienkowski8a474ff2018-08-07 21:31:33 +020042
43```
Francesco Servidio4ff0c182021-10-20 15:27:16 +020044 cd ~/mcuboot # or to your directory where MCUboot is cloned
Piotr Mienkowski8a474ff2018-08-07 21:31:33 +020045 pip3 install --user -r scripts/requirements.txt
46```
47
Carles Cufiecc34bb2018-01-22 18:02:46 +010048## Building the bootloader itself
49
50The bootloader is an ordinary Zephyr application, at least from
51Zephyr's point of view. There is a bit of configuration that needs to
52be made before building it. Most of this can be done as documented in
53the `CMakeLists.txt` file in boot/zephyr. There are comments there for
54guidance. It is important to select a signature algorithm, and decide
David Vincze2d736ad2019-02-18 11:50:22 +010055if the primary slot should be validated on every boot.
Carles Cufiecc34bb2018-01-22 18:02:46 +010056
57To build MCUboot, create a build directory in boot/zephyr, and build
58it as usual:
59
60```
61 cd boot/zephyr
Andrzej Puzdrowski75001562022-10-05 17:45:29 +020062 west build -b <board>
Carles Cufiecc34bb2018-01-22 18:02:46 +010063```
64
65In addition to the partitions defined in DTS, some additional
66information about the flash layout is currently required to build
67MCUboot itself. All the needed configuration is collected in
68`boot/zephyr/include/target.h`. Depending on the board, this information
69may come from board-specific headers, Device Tree, or be configured by
70MCUboot on a per-SoC family basis.
71
72After building the bootloader, the binaries should reside in
73`build/zephyr/zephyr.{bin,hex,elf}`, where `build` is the build
Andrzej Puzdrowski75001562022-10-05 17:45:29 +020074directory you chose when running `west build`. Use `west flash`
75to flash these binaries from the build directory. Depending
Carles Cufi5a9688a2018-04-03 17:10:18 +020076on the target and flash tool used, this might erase the whole of the flash
Francesco Servidio482921f2021-10-20 15:42:59 +020077memory (mass erase) or only the sectors where the bootloader resides prior to
Carles Cufi5a9688a2018-04-03 17:10:18 +020078programming the bootloader image itself.
Carles Cufiecc34bb2018-01-22 18:02:46 +010079
Francesco Servidio5bc98322021-11-03 13:19:22 +010080## Building applications for the bootloader
Carles Cufiecc34bb2018-01-22 18:02:46 +010081
82In addition to flash partitions in DTS, some additional configuration
83is required to build applications for MCUboot.
84
Carles Cufiefd783c2018-03-26 17:55:40 +020085This is handled internally by the Zephyr configuration system and is wrapped
86in the `CONFIG_BOOTLOADER_MCUBOOT` Kconfig variable, which must be enabled in
87the application's `prj.conf` file.
88
Carles Cufiecc34bb2018-01-22 18:02:46 +010089The directory `samples/zephyr/hello-world` in the MCUboot tree contains
90a simple application with everything you need. You can try it on your
91board and then just make a copy of it to get started on your own
92application; see samples/zephyr/README.md for a tutorial.
93
Carles Cufiefd783c2018-03-26 17:55:40 +020094The Zephyr `CONFIG_BOOTLOADER_MCUBOOT` configuration option
95[documentation](http://docs.zephyrproject.org/reference/kconfig/CONFIG_BOOTLOADER_MCUBOOT.html)
96provides additional details regarding the changes it makes to the image
97placement and generation in order for an application to be bootable by
98MCUboot.
Carles Cufiecc34bb2018-01-22 18:02:46 +010099
100With this, build the application as your normally would.
101
102### Signing the application
103
104In order to upgrade to an image (or even boot it, if
David Vincze2d736ad2019-02-18 11:50:22 +0100105`MCUBOOT_VALIDATE_PRIMARY_SLOT` is enabled), the images must be signed.
Carles Cufiecc34bb2018-01-22 18:02:46 +0100106To make development easier, MCUboot is distributed with some example
107keys. It is important to stress that these should never be used for
108production, since the private key is publicly available in this
109repository. See below on how to make your own signatures.
110
David Brown520e31c2018-04-05 14:38:08 -0600111Images can be signed with the `scripts/imgtool.py` script. It is best
112to look at `samples/zephyr/Makefile` for examples on how to use this.
Carles Cufiecc34bb2018-01-22 18:02:46 +0100113
114### Flashing the application
115
116The application itself can flashed with regular flash tools, but will
David Vincze2d736ad2019-02-18 11:50:22 +0100117need to be programmed at the offset of the primary slot for this particular
118target. Depending on the platform and flash tool you might need to manually
119specify a flash offset corresponding to the primary slot starting address. This
120is usually not relevant for flash tools that use Intel Hex images (.hex) instead
121of raw binary images (.bin) since the former include destination address
122information. Additionally you will need to make sure that the flash tool does
123not perform a mass erase (erasing the whole of the flash) or else you would be
124deleting MCUboot.
125These images can also be marked for upgrade, and loaded into the secondary slot,
Carles Cufiecc34bb2018-01-22 18:02:46 +0100126at which point the bootloader should perform an upgrade. It is up to
David Vincze2d736ad2019-02-18 11:50:22 +0100127the image to mark the primary slot as "image ok" before the next reboot,
Carles Cufiecc34bb2018-01-22 18:02:46 +0100128otherwise the bootloader will revert the application.
129
130## Managing signing keys
131
132The signing keys used by MCUboot are represented in standard formats,
133and can be generated and processed using conventional tools. However,
David Brown520e31c2018-04-05 14:38:08 -0600134`scripts/imgtool.py` is able to generate key pairs in all of the
135supported formats. See [the docs](imgtool.md) for more details on
136this tool.
Carles Cufiecc34bb2018-01-22 18:02:46 +0100137
138### Generating a new keypair
139
140Generating a keypair with imgtool is a matter of running the keygen
141subcommand:
142
143```
David Brown520e31c2018-04-05 14:38:08 -0600144 $ ./scripts/imgtool.py keygen -k mykey.pem -t rsa-2048
Carles Cufiecc34bb2018-01-22 18:02:46 +0100145```
146
147The argument to `-t` should be the desired key type. See the
David Brown520e31c2018-04-05 14:38:08 -0600148[the docs](imgtool.md) for more details on the possible key types.
Carles Cufiecc34bb2018-01-22 18:02:46 +0100149
150### Extracting the public key
151
152The generated keypair above contains both the public and the private
153key. It is necessary to extract the public key and insert it into the
Andrzej Puzdrowskia6a5c082022-10-05 18:14:42 +0200154bootloader. Use the ``CONFIG_BOOT_SIGNATURE_KEY_FILE`` Kconfig option to
155provide the path to the key file so the build system can extract
156the public key in a format usable by the C compiler.
157The generated public key is saved in `build/zephyr/autogen-pubkey.h`, which is included
158by the `boot/zephyr/keys.c`.
Carles Cufiecc34bb2018-01-22 18:02:46 +0100159
Andrzej Puzdrowskia6a5c082022-10-05 18:14:42 +0200160Currently, the Zephyr RTOS port limits its support to one keypair at the time,
161although MCUboot's key management infrastructure supports multiple keypairs.
Carles Cufiecc34bb2018-01-22 18:02:46 +0100162
Andrzej Puzdrowskia6a5c082022-10-05 18:14:42 +0200163Once MCUboot is built, this new keypair file (`mykey.pem` in this
Carles Cufiecc34bb2018-01-22 18:02:46 +0100164example) can be used to sign images.
Jamie McCrae0b7b7ae2022-12-19 11:43:54 +0000165
166## Using swap-using-scratch flash algorithm
167
168To use the swap-using-scratch flash algorithm, a scratch partition needs to be
169present for the target board which is used for holding the data being swapped
170from both slots, this section must be at least as big as the largest sector
171size of the 2 partitions (e.g. if a device has a primary slot in main flash
172with a sector size of 512 bytes and secondar slot in external off-chip flash
173with a sector size of 4KB then the scratch area must be at least 4KB in size).
174The number of sectors must also be evenly divisable by this sector size, e.g.
1754KB, 8KB, 12KB, 16KB are allowed, 7KB, 7.5KB are not. This scratch partition
176needs adding to the .dts file for the board, e.g. for the nrf52dk_nrf52832
177board thus would involve updating
178`<zephyr>/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts` with:
179
180```
181 boot_partition: partition@0 {
182 label = "mcuboot";
183 reg = <0x00000000 0xc000>;
184 };
185 slot0_partition: partition@c000 {
186 label = "image-0";
187 reg = <0x0000C000 0x37000>;
188 };
189 slot1_partition: partition@43000 {
190 label = "image-1";
191 reg = <0x00043000 0x37000>;
192 };
193 storage_partition: partition@7a000 {
194 label = "storage";
195 reg = <0x0007a000 0x00006000>;
196 };
197```
198
199Which would make the application size 220KB and scratch size 24KB (the nRF52832
200has a 4KB sector size so the size of the scratch partition can be reduced at
201the cost of vastly reducing flash lifespan, e.g. for a 32KB firmware update
202with an 8KB scratch area, the scratch area would be erased and programmed 8
203times per image upgrade/revert). To configure MCUboot to work in
204swap-using-scratch mode, the Kconfig value must be set when building it:
205`CONFIG_BOOT_SWAP_USING_SCRATCH=y`.
206
207Note that it is possible for an application to get into a stuck state when
208swap-using-scratch is used whereby an application has loaded a firmware update
209and marked it as test/confirmed but MCUboot will not swap the images and
210erasing the secondary slot from the zephyr application returns an error
211because the slot is marked for upgrade.