| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 1 | # Building and using MCUboot with Zephyr | 
|  | 2 |  | 
|  | 3 | MCUboot began its life as the bootloader for Mynewt.  It has since | 
|  | 4 | acquired the ability to be used as a bootloader for Zephyr as well. | 
|  | 5 | There are some pretty significant differences in how apps are built | 
|  | 6 | for Zephyr, and these are documented here. | 
|  | 7 |  | 
| Fabio Utzig | 4dce6aa | 2018-02-12 15:31:32 -0200 | [diff] [blame] | 8 | Please see the [design document](design.md) for documentation on the design | 
|  | 9 | and operation of the bootloader itself. This functionality should be the same | 
|  | 10 | on all supported RTOSs. | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 11 |  | 
|  | 12 | The first step required for Zephyr is making sure your board has flash | 
|  | 13 | partitions defined in its device tree. These partitions are: | 
|  | 14 |  | 
|  | 15 | - `boot_partition`: for MCUboot itself | 
| Andrzej Puzdrowski | 7500156 | 2022-10-05 17:45:29 +0200 | [diff] [blame] | 16 | - `slot0_partition`: the primary slot of Image 0 | 
|  | 17 | - `slot1_partition`: the secondary slot of Image 0 | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 18 | - `scratch_partition`: the scratch slot | 
|  | 19 |  | 
|  | 20 | Currently, the two image slots must be contiguous. If you are running | 
|  | 21 | MCUboot as your stage 1 bootloader, `boot_partition` must be configured | 
| David Vincze | ba3bd60 | 2019-06-17 16:01:43 +0200 | [diff] [blame] | 22 | so your SoC runs it out of reset. If there are multiple updateable images | 
|  | 23 | then the corresponding primary and secondary partitions must be defined for | 
| Andrzej Puzdrowski | 7500156 | 2022-10-05 17:45:29 +0200 | [diff] [blame] | 24 | the rest of the images too (for example, `slot2_partition` and | 
|  | 25 | `slot3_partition` for Image 1). | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 26 |  | 
|  | 27 | The flash partitions are typically defined in the Zephyr boards folder, in a | 
|  | 28 | file named `boards/<arch>/<board>/<board>.dts`. An example `.dts` file with | 
|  | 29 | flash partitions defined is the frdm_k64f's in | 
| Andrzej Puzdrowski | 7500156 | 2022-10-05 17:45:29 +0200 | [diff] [blame] | 30 | `boards/arm/frdm_k64f/frdm_k64f.dts`. Make sure the DT node labels in your board's | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 31 | `.dts` file match the ones used there. | 
|  | 32 |  | 
| Francesco Servidio | 5bc9832 | 2021-11-03 13:19:22 +0100 | [diff] [blame] | 33 | ## Installing requirements and dependencies | 
| Piotr Mienkowski | 8a474ff | 2018-08-07 21:31:33 +0200 | [diff] [blame] | 34 |  | 
| Francesco Servidio | 4ff0c18 | 2021-10-20 15:27:16 +0200 | [diff] [blame] | 35 | Install additional packages required for development with MCUboot: | 
| Piotr Mienkowski | 8a474ff | 2018-08-07 21:31:33 +0200 | [diff] [blame] | 36 |  | 
|  | 37 | ``` | 
| Francesco Servidio | 4ff0c18 | 2021-10-20 15:27:16 +0200 | [diff] [blame] | 38 | cd ~/mcuboot  # or to your directory where MCUboot is cloned | 
| Piotr Mienkowski | 8a474ff | 2018-08-07 21:31:33 +0200 | [diff] [blame] | 39 | pip3 install --user -r scripts/requirements.txt | 
|  | 40 | ``` | 
|  | 41 |  | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 42 | ## Building the bootloader itself | 
|  | 43 |  | 
|  | 44 | The bootloader is an ordinary Zephyr application, at least from | 
|  | 45 | Zephyr's point of view.  There is a bit of configuration that needs to | 
|  | 46 | be made before building it.  Most of this can be done as documented in | 
|  | 47 | the `CMakeLists.txt` file in boot/zephyr.  There are comments there for | 
|  | 48 | guidance.  It is important to select a signature algorithm, and decide | 
| David Vincze | 2d736ad | 2019-02-18 11:50:22 +0100 | [diff] [blame] | 49 | if the primary slot should be validated on every boot. | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 50 |  | 
|  | 51 | To build MCUboot, create a build directory in boot/zephyr, and build | 
|  | 52 | it as usual: | 
|  | 53 |  | 
|  | 54 | ``` | 
|  | 55 | cd boot/zephyr | 
| Andrzej Puzdrowski | 7500156 | 2022-10-05 17:45:29 +0200 | [diff] [blame] | 56 | west build -b <board> | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 57 | ``` | 
|  | 58 |  | 
|  | 59 | In addition to the partitions defined in DTS, some additional | 
|  | 60 | information about the flash layout is currently required to build | 
|  | 61 | MCUboot itself. All the needed configuration is collected in | 
|  | 62 | `boot/zephyr/include/target.h`. Depending on the board, this information | 
|  | 63 | may come from board-specific headers, Device Tree, or be configured by | 
|  | 64 | MCUboot on a per-SoC family basis. | 
|  | 65 |  | 
|  | 66 | After building the bootloader, the binaries should reside in | 
|  | 67 | `build/zephyr/zephyr.{bin,hex,elf}`, where `build` is the build | 
| Andrzej Puzdrowski | 7500156 | 2022-10-05 17:45:29 +0200 | [diff] [blame] | 68 | directory you chose when running `west build`. Use `west flash` | 
|  | 69 | to flash these binaries from the build directory. Depending | 
| Carles Cufi | 5a9688a | 2018-04-03 17:10:18 +0200 | [diff] [blame] | 70 | on the target and flash tool used, this might erase the whole of the flash | 
| Francesco Servidio | 482921f | 2021-10-20 15:42:59 +0200 | [diff] [blame] | 71 | memory (mass erase) or only the sectors where the bootloader resides prior to | 
| Carles Cufi | 5a9688a | 2018-04-03 17:10:18 +0200 | [diff] [blame] | 72 | programming the bootloader image itself. | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 73 |  | 
| Francesco Servidio | 5bc9832 | 2021-11-03 13:19:22 +0100 | [diff] [blame] | 74 | ## Building applications for the bootloader | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 75 |  | 
|  | 76 | In addition to flash partitions in DTS, some additional configuration | 
|  | 77 | is required to build applications for MCUboot. | 
|  | 78 |  | 
| Carles Cufi | efd783c | 2018-03-26 17:55:40 +0200 | [diff] [blame] | 79 | This is handled internally by the Zephyr configuration system and is wrapped | 
|  | 80 | in the `CONFIG_BOOTLOADER_MCUBOOT` Kconfig variable, which must be enabled in | 
|  | 81 | the application's `prj.conf` file. | 
|  | 82 |  | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 83 | The directory `samples/zephyr/hello-world` in the MCUboot tree contains | 
|  | 84 | a simple application with everything you need. You can try it on your | 
|  | 85 | board and then just make a copy of it to get started on your own | 
|  | 86 | application; see samples/zephyr/README.md for a tutorial. | 
|  | 87 |  | 
| Carles Cufi | efd783c | 2018-03-26 17:55:40 +0200 | [diff] [blame] | 88 | The Zephyr `CONFIG_BOOTLOADER_MCUBOOT` configuration option | 
|  | 89 | [documentation](http://docs.zephyrproject.org/reference/kconfig/CONFIG_BOOTLOADER_MCUBOOT.html) | 
|  | 90 | provides additional details regarding the changes it makes to the image | 
|  | 91 | placement and generation in order for an application to be bootable by | 
|  | 92 | MCUboot. | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 93 |  | 
|  | 94 | With this, build the application as your normally would. | 
|  | 95 |  | 
|  | 96 | ### Signing the application | 
|  | 97 |  | 
|  | 98 | In order to upgrade to an image (or even boot it, if | 
| David Vincze | 2d736ad | 2019-02-18 11:50:22 +0100 | [diff] [blame] | 99 | `MCUBOOT_VALIDATE_PRIMARY_SLOT` is enabled), the images must be signed. | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 100 | To make development easier, MCUboot is distributed with some example | 
|  | 101 | keys.  It is important to stress that these should never be used for | 
|  | 102 | production, since the private key is publicly available in this | 
|  | 103 | repository.  See below on how to make your own signatures. | 
|  | 104 |  | 
| David Brown | 520e31c | 2018-04-05 14:38:08 -0600 | [diff] [blame] | 105 | Images can be signed with the `scripts/imgtool.py` script.  It is best | 
|  | 106 | to look at `samples/zephyr/Makefile` for examples on how to use this. | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 107 |  | 
|  | 108 | ### Flashing the application | 
|  | 109 |  | 
|  | 110 | The application itself can flashed with regular flash tools, but will | 
| David Vincze | 2d736ad | 2019-02-18 11:50:22 +0100 | [diff] [blame] | 111 | need to be programmed at the offset of the primary slot for this particular | 
|  | 112 | target. Depending on the platform and flash tool you might need to manually | 
|  | 113 | specify a flash offset corresponding to the primary slot starting address. This | 
|  | 114 | is usually not relevant for flash tools that use Intel Hex images (.hex) instead | 
|  | 115 | of raw binary images (.bin) since the former include destination address | 
|  | 116 | information. Additionally you will need to make sure that the flash tool does | 
|  | 117 | not perform a mass erase (erasing the whole of the flash) or else you would be | 
|  | 118 | deleting MCUboot. | 
|  | 119 | These images can also be marked for upgrade, and loaded into the secondary slot, | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 120 | at which point the bootloader should perform an upgrade.  It is up to | 
| David Vincze | 2d736ad | 2019-02-18 11:50:22 +0100 | [diff] [blame] | 121 | the image to mark the primary slot as "image ok" before the next reboot, | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 122 | otherwise the bootloader will revert the application. | 
|  | 123 |  | 
|  | 124 | ## Managing signing keys | 
|  | 125 |  | 
|  | 126 | The signing keys used by MCUboot are represented in standard formats, | 
|  | 127 | and can be generated and processed using conventional tools.  However, | 
| David Brown | 520e31c | 2018-04-05 14:38:08 -0600 | [diff] [blame] | 128 | `scripts/imgtool.py` is able to generate key pairs in all of the | 
|  | 129 | supported formats.  See [the docs](imgtool.md) for more details on | 
|  | 130 | this tool. | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 131 |  | 
|  | 132 | ### Generating a new keypair | 
|  | 133 |  | 
|  | 134 | Generating a keypair with imgtool is a matter of running the keygen | 
|  | 135 | subcommand: | 
|  | 136 |  | 
|  | 137 | ``` | 
| David Brown | 520e31c | 2018-04-05 14:38:08 -0600 | [diff] [blame] | 138 | $ ./scripts/imgtool.py keygen -k mykey.pem -t rsa-2048 | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 139 | ``` | 
|  | 140 |  | 
|  | 141 | The argument to `-t` should be the desired key type.  See the | 
| David Brown | 520e31c | 2018-04-05 14:38:08 -0600 | [diff] [blame] | 142 | [the docs](imgtool.md) for more details on the possible key types. | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 143 |  | 
|  | 144 | ### Extracting the public key | 
|  | 145 |  | 
|  | 146 | The generated keypair above contains both the public and the private | 
|  | 147 | key.  It is necessary to extract the public key and insert it into the | 
| Andrzej Puzdrowski | a6a5c08 | 2022-10-05 18:14:42 +0200 | [diff] [blame] | 148 | bootloader.  Use the ``CONFIG_BOOT_SIGNATURE_KEY_FILE`` Kconfig option to | 
|  | 149 | provide the path to the key file so the build system can extract | 
|  | 150 | the public key in a format usable by the C compiler. | 
|  | 151 | The generated public key is saved in `build/zephyr/autogen-pubkey.h`, which is included | 
|  | 152 | by the `boot/zephyr/keys.c`. | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 153 |  | 
| Andrzej Puzdrowski | a6a5c08 | 2022-10-05 18:14:42 +0200 | [diff] [blame] | 154 | Currently, the Zephyr RTOS port limits its support to one keypair at the time, | 
|  | 155 | although MCUboot's key management infrastructure supports multiple keypairs. | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 156 |  | 
| Andrzej Puzdrowski | a6a5c08 | 2022-10-05 18:14:42 +0200 | [diff] [blame] | 157 | Once MCUboot is built, this new keypair file (`mykey.pem` in this | 
| Carles Cufi | ecc34bb | 2018-01-22 18:02:46 +0100 | [diff] [blame] | 158 | example) can be used to sign images. |