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