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