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 
85 /**
86  * @brief MCUboot image header representation for image version
87  *
88  * The header for an MCUboot firmware image contains an embedded
89  * version number, in semantic versioning format. This structure
90  * represents the information it contains.
91  */
92 struct mcuboot_img_sem_ver {
93 	uint8_t major;
94 	uint8_t minor;
95 	uint16_t revision;
96 	uint32_t build_num;
97 };
98 
99 /**
100  * @brief Model for the MCUboot image header as of version 1
101  *
102  * This represents the data present in the image header, in version 1
103  * of the header format.
104  *
105  * Some information present in the header but not currently relevant
106  * to applications is omitted.
107  */
108 struct mcuboot_img_header_v1 {
109 	/** The size of the image, in bytes. */
110 	uint32_t image_size;
111 	/** The image version. */
112 	struct mcuboot_img_sem_ver sem_ver;
113 };
114 
115 /**
116  * @brief Model for the MCUBoot image header
117  *
118  * This contains the decoded image header, along with the major
119  * version of MCUboot that the header was built for.
120  *
121  * (The MCUboot project guarantees that incompatible changes to the
122  * image header will result in major version changes to the bootloader
123  * itself, and will be detectable in the persistent representation of
124  * the header.)
125  */
126 struct mcuboot_img_header {
127 	/**
128 	 * The version of MCUboot the header is built for.
129 	 *
130 	 * The value 1 corresponds to MCUboot versions 1.x.y.
131 	 */
132 	uint32_t mcuboot_version;
133 	/**
134 	 * The header information. It is only valid to access fields
135 	 * in the union member corresponding to the mcuboot_version
136 	 * field above.
137 	 */
138 	union {
139 		/** Header information for MCUboot version 1. */
140 		struct mcuboot_img_header_v1 v1;
141 	} h;
142 };
143 
144 /**
145  * @brief Read the MCUboot image header information from an image bank.
146  *
147  * This attempts to parse the image header,
148  * From the start of the @a area_id image.
149  *
150  * @param area_id flash_area ID of image bank which stores the image.
151  * @param header On success, the returned header information is available
152  *               in this structure.
153  * @param header_size Size of the header structure passed by the caller.
154  *                    If this is not large enough to contain all of the
155  *                    necessary information, an error is returned.
156  * @return Zero on success, a negative value on error.
157  */
158 int boot_read_bank_header(uint8_t area_id,
159 			  struct mcuboot_img_header *header,
160 			  size_t header_size);
161 
162 /**
163  * @brief Check if the currently running image is confirmed as OK.
164  *
165  * MCUboot can perform "test" upgrades. When these occur, a new
166  * firmware image is installed and booted, but the old version will be
167  * reverted at the next reset unless the new image explicitly marks
168  * itself OK.
169  *
170  * This routine can be used to check if the currently running image
171  * has been marked as OK.
172  *
173  * @return True if the image is confirmed as OK, false otherwise.
174  * @see boot_write_img_confirmed()
175  */
176 bool boot_is_img_confirmed(void);
177 
178 /**
179  * @brief Marks the currently running image as confirmed.
180  *
181  * This routine attempts to mark the currently running firmware image
182  * as OK, which will install it permanently, preventing MCUboot from
183  * reverting it for an older image at the next reset.
184  *
185  * This routine is safe to call if the current image has already been
186  * confirmed. It will return a successful result in this case.
187  *
188  * @return 0 on success, negative errno code on fail.
189  */
190 int boot_write_img_confirmed(void);
191 
192 /**
193  * @brief Marks the image with the given index in the primary slot as confirmed.
194  *
195  * This routine attempts to mark the firmware image in the primary slot
196  * as OK, which will install it permanently, preventing MCUboot from
197  * reverting it for an older image at the next reset.
198  *
199  * This routine is safe to call if the current image has already been
200  * confirmed. It will return a successful result in this case.
201  *
202  * @param image_index Image pair index.
203  *
204  * @return 0 on success, negative errno code on fail.
205  */
206 int boot_write_img_confirmed_multi(int image_index);
207 
208 /**
209  * @brief Determines the action, if any, that mcuboot will take on the next
210  * reboot.
211  * @return a BOOT_SWAP_TYPE_[...] constant on success, negative errno code on
212  * fail.
213  */
214 int mcuboot_swap_type(void);
215 
216 /**
217  * @brief Determines the action, if any, that mcuboot will take on the next
218  * reboot.
219  *
220  * @param image_index Image pair index.
221  *
222  * @return a BOOT_SWAP_TYPE_[...] constant on success, negative errno code on
223  * fail.
224  */
225 int mcuboot_swap_type_multi(int image_index);
226 
227 
228 /** Boot upgrade request modes */
229 #define BOOT_UPGRADE_TEST       0
230 #define BOOT_UPGRADE_PERMANENT  1
231 
232 /**
233  * @brief Marks the image in slot 1 as pending. On the next reboot, the system
234  * will perform a boot of the slot 1 image.
235  *
236  * @param permanent Whether the image should be used permanently or
237  * only tested once:
238  *   BOOT_UPGRADE_TEST=run image once, then confirm or revert.
239  *   BOOT_UPGRADE_PERMANENT=run image forever.
240  * @return 0 on success, negative errno code on fail.
241  */
242 int boot_request_upgrade(int permanent);
243 
244 /**
245  * @brief Marks the image with the given index in the secondary slot as pending.
246  * On the next reboot, the system will perform a boot of the secondary slot
247  * image.
248  *
249  * @param image_index Image pair index.
250  * @param permanent Whether the image should be used permanently or
251  * only tested once:
252  *   BOOT_UPGRADE_TEST=run image once, then confirm or revert.
253  *   BOOT_UPGRADE_PERMANENT=run image forever.
254  * @return 0 on success, negative errno code on fail.
255  */
256 int boot_request_upgrade_multi(int image_index, int permanent);
257 
258 /**
259  * @brief Erase the image Bank.
260  *
261  * @param area_id flash_area ID of image bank to be erased.
262  * @return 0 on success, negative errno code on fail.
263  */
264 int boot_erase_img_bank(uint8_t area_id);
265 
266 /**
267  * @brief Get the offset of the status in the image bank
268  *
269  * @param area_id flash_area ID of image bank to get the status offset
270  * @return a positive offset on success, negative errno code on fail
271  */
272 ssize_t boot_get_area_trailer_status_offset(uint8_t area_id);
273 
274 /**
275  * @brief Get the offset of the status from an image bank size
276  *
277  * @param area_size size of image bank
278  * @return offset of the status. When negative the status will not fit
279  * the given size
280  */
281 ssize_t boot_get_trailer_status_offset(size_t area_size);
282 
283 #ifdef __cplusplus
284 }
285 #endif
286 
287 /**
288  * @}
289  */
290 
291 #endif  /* ZEPHYR_INCLUDE_DFU_MCUBOOT_H_ */
292