1 /* 2 * Copyright (c) 2017 Nordic Semiconductor ASA 3 * Copyright (c) 2016 Linaro Limited 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 /** 9 * @file 10 * @brief MCUboot public API for MCUboot control of image boot process 11 * 12 * The header declares API functions that can be used to get information 13 * on and select application images for boot. 14 */ 15 16 #ifndef ZEPHYR_INCLUDE_DFU_MCUBOOT_H_ 17 #define ZEPHYR_INCLUDE_DFU_MCUBOOT_H_ 18 19 #include <stdbool.h> 20 #include <stddef.h> 21 #include <sys/types.h> 22 23 #include <zephyr/types.h> 24 25 /** 26 * @brief MCUboot public API for MCUboot control of image boot process 27 * 28 * @defgroup mcuboot_api MCUboot image control API 29 * @ingroup third_party 30 * @{ 31 */ 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 #ifdef BOOT_SWAP_TYPE_NONE 38 #if BOOT_SWAP_TYPE_NONE != 1 /*ensure the same definition in MCUboot */ 39 #error "definition incompatible" 40 #endif 41 #else 42 /** Attempt to boot the contents of slot 0. */ 43 #define BOOT_SWAP_TYPE_NONE 1 44 #endif 45 46 #ifdef BOOT_SWAP_TYPE_TEST 47 #if BOOT_SWAP_TYPE_TEST != 2 /*ensure the same definition in MCUboot */ 48 #error "definition incompatible" 49 #endif 50 #else 51 /** Swap to slot 1. Absent a confirm command, revert back on next boot. */ 52 #define BOOT_SWAP_TYPE_TEST 2 53 #endif 54 55 #ifdef BOOT_SWAP_TYPE_PERM 56 #if BOOT_SWAP_TYPE_PERM != 3 /*ensure the same definition in MCUboot */ 57 #error "definition incompatible" 58 #endif 59 #else 60 /** Swap to slot 1, and permanently switch to booting its contents. */ 61 #define BOOT_SWAP_TYPE_PERM 3 62 #endif 63 64 #ifdef BOOT_SWAP_TYPE_REVERT 65 #if BOOT_SWAP_TYPE_REVERT != 4 /*ensure the same definition in MCUboot */ 66 #error "definition incompatible" 67 #endif 68 #else 69 /** Swap back to alternate slot. A confirm changes this state to NONE. */ 70 #define BOOT_SWAP_TYPE_REVERT 4 71 #endif 72 73 #ifdef BOOT_SWAP_TYPE_FAIL 74 #if BOOT_SWAP_TYPE_FAIL != 5 /*ensure the same definition in MCUboot */ 75 #error "definition incompatible" 76 #endif 77 #else 78 /** Swap failed because image to be run is not valid */ 79 #define BOOT_SWAP_TYPE_FAIL 5 80 #endif 81 82 #define BOOT_IMG_VER_STRLEN_MAX 25 /* 255.255.65535.4294967295\0 */ 83 84 /** Sector at which firmware update should be placed by application in swap using offset mode */ 85 #define SWAP_USING_OFFSET_SECTOR_UPDATE_BEGIN 1 86 87 /** 88 * @brief MCUboot image header representation for image version 89 * 90 * The header for an MCUboot firmware image contains an embedded 91 * version number, in semantic versioning format. This structure 92 * represents the information it contains. 93 */ 94 struct mcuboot_img_sem_ver { 95 uint8_t major; 96 uint8_t minor; 97 uint16_t revision; 98 uint32_t build_num; 99 }; 100 101 /** 102 * @brief Model for the MCUboot image header as of version 1 103 * 104 * This represents the data present in the image header, in version 1 105 * of the header format. 106 * 107 * Some information present in the header but not currently relevant 108 * to applications is omitted. 109 */ 110 struct mcuboot_img_header_v1 { 111 /** The size of the image, in bytes. */ 112 uint32_t image_size; 113 /** The image version. */ 114 struct mcuboot_img_sem_ver sem_ver; 115 }; 116 117 /** 118 * @brief Model for the MCUBoot image header 119 * 120 * This contains the decoded image header, along with the major 121 * version of MCUboot that the header was built for. 122 * 123 * (The MCUboot project guarantees that incompatible changes to the 124 * image header will result in major version changes to the bootloader 125 * itself, and will be detectable in the persistent representation of 126 * the header.) 127 */ 128 struct mcuboot_img_header { 129 /** 130 * The version of MCUboot the header is built for. 131 * 132 * The value 1 corresponds to MCUboot versions 1.x.y. 133 */ 134 uint32_t mcuboot_version; 135 /** 136 * The header information. It is only valid to access fields 137 * in the union member corresponding to the mcuboot_version 138 * field above. 139 */ 140 union { 141 /** Header information for MCUboot version 1. */ 142 struct mcuboot_img_header_v1 v1; 143 } h; 144 }; 145 146 /** 147 * @brief Read the MCUboot image header information from an image bank. 148 * 149 * This attempts to parse the image header, 150 * From the start of the @a area_id image. 151 * 152 * @param area_id flash_area ID of image bank which stores the image. 153 * @param header On success, the returned header information is available 154 * in this structure. 155 * @param header_size Size of the header structure passed by the caller. 156 * If this is not large enough to contain all of the 157 * necessary information, an error is returned. 158 * @return Zero on success, a negative value on error. 159 */ 160 int boot_read_bank_header(uint8_t area_id, 161 struct mcuboot_img_header *header, 162 size_t header_size); 163 164 /** 165 * @brief Get the flash area id for the active image slot. 166 * 167 * @return flash area id for the active image slot 168 */ 169 uint8_t boot_fetch_active_slot(void); 170 171 /** 172 * @brief Check if the currently running image is confirmed as OK. 173 * 174 * MCUboot can perform "test" upgrades. When these occur, a new 175 * firmware image is installed and booted, but the old version will be 176 * reverted at the next reset unless the new image explicitly marks 177 * itself OK. 178 * 179 * This routine can be used to check if the currently running image 180 * has been marked as OK. 181 * 182 * @return True if the image is confirmed as OK, false otherwise. 183 * @see boot_write_img_confirmed() 184 */ 185 bool boot_is_img_confirmed(void); 186 187 /** 188 * @brief Marks the currently running image as confirmed. 189 * 190 * This routine attempts to mark the currently running firmware image 191 * as OK, which will install it permanently, preventing MCUboot from 192 * reverting it for an older image at the next reset. 193 * 194 * This routine is safe to call if the current image has already been 195 * confirmed. It will return a successful result in this case. 196 * 197 * @return 0 on success, negative errno code on fail. 198 */ 199 int boot_write_img_confirmed(void); 200 201 /** 202 * @brief Marks the image with the given index in the primary slot as confirmed. 203 * 204 * This routine attempts to mark the firmware image in the primary slot 205 * as OK, which will install it permanently, preventing MCUboot from 206 * reverting it for an older image at the next reset. 207 * 208 * This routine is safe to call if the current image has already been 209 * confirmed. It will return a successful result in this case. 210 * 211 * @param image_index Image pair index. 212 * 213 * @return 0 on success, negative errno code on fail. 214 */ 215 int boot_write_img_confirmed_multi(int image_index); 216 217 /** 218 * @brief Determines the action, if any, that mcuboot will take on the next 219 * reboot. 220 * @return a BOOT_SWAP_TYPE_[...] constant on success, negative errno code on 221 * fail. 222 */ 223 int mcuboot_swap_type(void); 224 225 /** 226 * @brief Determines the action, if any, that mcuboot will take on the next 227 * reboot. 228 * 229 * @param image_index Image pair index. 230 * 231 * @return a BOOT_SWAP_TYPE_[...] constant on success, negative errno code on 232 * fail. 233 */ 234 int mcuboot_swap_type_multi(int image_index); 235 236 237 /** Boot upgrade request modes */ 238 #define BOOT_UPGRADE_TEST 0 239 #define BOOT_UPGRADE_PERMANENT 1 240 241 /** 242 * @brief Marks the image in slot 1 as pending. On the next reboot, the system 243 * will perform a boot of the slot 1 image. 244 * 245 * @param permanent Whether the image should be used permanently or 246 * only tested once: 247 * BOOT_UPGRADE_TEST=run image once, then confirm or revert. 248 * BOOT_UPGRADE_PERMANENT=run image forever. 249 * @return 0 on success, negative errno code on fail. 250 */ 251 int boot_request_upgrade(int permanent); 252 253 /** 254 * @brief Marks the image with the given index in the secondary slot as pending. 255 * On the next reboot, the system will perform a boot of the secondary slot 256 * image. 257 * 258 * @param image_index Image pair index. 259 * @param permanent Whether the image should be used permanently or 260 * only tested once: 261 * BOOT_UPGRADE_TEST=run image once, then confirm or revert. 262 * BOOT_UPGRADE_PERMANENT=run image forever. 263 * @return 0 on success, negative errno code on fail. 264 */ 265 int boot_request_upgrade_multi(int image_index, int permanent); 266 267 /** 268 * @brief Erase the image Bank. 269 * 270 * @param area_id flash_area ID of image bank to be erased. 271 * @return 0 on success, negative errno code on fail. 272 */ 273 int boot_erase_img_bank(uint8_t area_id); 274 275 /** 276 * @brief Get the offset of the status in the image bank 277 * 278 * @param area_id flash_area ID of image bank to get the status offset 279 * @return a positive offset on success, negative errno code on fail 280 */ 281 ssize_t boot_get_area_trailer_status_offset(uint8_t area_id); 282 283 /** 284 * @brief Get the offset of the status from an image bank size 285 * 286 * @param area_size size of image bank 287 * @return offset of the status. When negative the status will not fit 288 * the given size 289 */ 290 ssize_t boot_get_trailer_status_offset(size_t area_size); 291 292 #if defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_USING_OFFSET) || defined(__DOXYGEN__) 293 /** 294 * @brief Get the offset of the image header, this should be used in swap using offset mode to 295 * account for the secondary slot data starting in the first or second sector, depending 296 * upon the current state 297 * 298 * @param area_id flash_area ID of image bank to get the status offset 299 * @return offset of the image header 300 */ 301 size_t boot_get_image_start_offset(uint8_t area_id); 302 #else 303 #define boot_get_image_start_offset(...) 0 304 #endif 305 306 #ifdef __cplusplus 307 } 308 #endif 309 310 /** 311 * @} 312 */ 313 314 #endif /* ZEPHYR_INCLUDE_DFU_MCUBOOT_H_ */ 315