]>
Commit | Line | Data |
---|---|---|
27d15611 AD |
1 | /* |
2 | * This is from the Android Project, | |
3 | * Repository: https://android.googlesource.com/platform/bootable/recovery | |
4 | * File: bootloader_message/include/bootloader_message/bootloader_message.h | |
0381b713 | 5 | * Commit: See U-Boot commit description |
27d15611 AD |
6 | * |
7 | * Copyright (C) 2008 The Android Open Source Project | |
8 | * | |
9 | * SPDX-License-Identifier: BSD-3-Clause | |
10 | */ | |
11 | ||
12 | #ifndef __ANDROID_BOOTLOADER_MESSAGE_H | |
13 | #define __ANDROID_BOOTLOADER_MESSAGE_H | |
14 | ||
0381b713 ER |
15 | #ifndef __UBOOT__ |
16 | #include <assert.h> | |
17 | #include <stddef.h> | |
18 | #include <stdint.h> | |
19 | #else | |
27d15611 AD |
20 | /* compiler.h defines the types that otherwise are included from stdint.h and |
21 | * stddef.h | |
22 | */ | |
23 | #include <compiler.h> | |
0381b713 | 24 | #endif |
27d15611 | 25 | |
0381b713 ER |
26 | // Spaces used by misc partition are as below: |
27 | // 0 - 2K For bootloader_message | |
28 | // 2K - 16K Used by Vendor's bootloader (the 2K - 4K range may be optionally used | |
29 | // as bootloader_message_ab struct) | |
30 | // 16K - 64K Used by uncrypt and recovery to store wipe_package for A/B devices | |
31 | // Note that these offsets are admitted by bootloader,recovery and uncrypt, so they | |
32 | // are not configurable without changing all of them. | |
27d15611 AD |
33 | static const size_t BOOTLOADER_MESSAGE_OFFSET_IN_MISC = 0; |
34 | static const size_t WIPE_PACKAGE_OFFSET_IN_MISC = 16 * 1024; | |
35 | ||
36 | /* Bootloader Message (2-KiB) | |
37 | * | |
38 | * This structure describes the content of a block in flash | |
39 | * that is used for recovery and the bootloader to talk to | |
40 | * each other. | |
41 | * | |
42 | * The command field is updated by linux when it wants to | |
43 | * reboot into recovery or to update radio or bootloader firmware. | |
44 | * It is also updated by the bootloader when firmware update | |
45 | * is complete (to boot into recovery for any final cleanup) | |
46 | * | |
47 | * The status field was used by the bootloader after the completion | |
48 | * of an "update-radio" or "update-hboot" command, which has been | |
49 | * deprecated since Froyo. | |
50 | * | |
51 | * The recovery field is only written by linux and used | |
52 | * for the system to send a message to recovery or the | |
53 | * other way around. | |
54 | * | |
55 | * The stage field is written by packages which restart themselves | |
56 | * multiple times, so that the UI can reflect which invocation of the | |
57 | * package it is. If the value is of the format "#/#" (eg, "1/3"), | |
58 | * the UI will add a simple indicator of that status. | |
59 | * | |
60 | * We used to have slot_suffix field for A/B boot control metadata in | |
61 | * this struct, which gets unintentionally cleared by recovery or | |
62 | * uncrypt. Move it into struct bootloader_message_ab to avoid the | |
63 | * issue. | |
64 | */ | |
65 | struct bootloader_message { | |
66 | char command[32]; | |
67 | char status[32]; | |
68 | char recovery[768]; | |
69 | ||
0381b713 ER |
70 | // The 'recovery' field used to be 1024 bytes. It has only ever |
71 | // been used to store the recovery command line, so 768 bytes | |
72 | // should be plenty. We carve off the last 256 bytes to store the | |
73 | // stage string (for multistage packages) and possible future | |
74 | // expansion. | |
27d15611 AD |
75 | char stage[32]; |
76 | ||
0381b713 ER |
77 | // The 'reserved' field used to be 224 bytes when it was initially |
78 | // carved off from the 1024-byte recovery field. Bump it up to | |
79 | // 1184-byte so that the entire bootloader_message struct rounds up | |
80 | // to 2048-byte. | |
27d15611 AD |
81 | char reserved[1184]; |
82 | }; | |
83 | ||
84 | /** | |
85 | * We must be cautious when changing the bootloader_message struct size, | |
86 | * because A/B-specific fields may end up with different offsets. | |
87 | */ | |
0381b713 | 88 | #ifndef __UBOOT__ |
27d15611 AD |
89 | #if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus) |
90 | static_assert(sizeof(struct bootloader_message) == 2048, | |
91 | "struct bootloader_message size changes, which may break A/B devices"); | |
92 | #endif | |
0381b713 | 93 | #endif /* __UBOOT__ */ |
27d15611 AD |
94 | |
95 | /** | |
96 | * The A/B-specific bootloader message structure (4-KiB). | |
97 | * | |
98 | * We separate A/B boot control metadata from the regular bootloader | |
99 | * message struct and keep it here. Everything that's A/B-specific | |
100 | * stays after struct bootloader_message, which should be managed by | |
101 | * the A/B-bootloader or boot control HAL. | |
102 | * | |
103 | * The slot_suffix field is used for A/B implementations where the | |
104 | * bootloader does not set the androidboot.ro.boot.slot_suffix kernel | |
105 | * commandline parameter. This is used by fs_mgr to mount /system and | |
106 | * other partitions with the slotselect flag set in fstab. A/B | |
107 | * implementations are free to use all 32 bytes and may store private | |
108 | * data past the first NUL-byte in this field. It is encouraged, but | |
109 | * not mandatory, to use 'struct bootloader_control' described below. | |
110 | * | |
111 | * The update_channel field is used to store the Omaha update channel | |
112 | * if update_engine is compiled with Omaha support. | |
113 | */ | |
114 | struct bootloader_message_ab { | |
115 | struct bootloader_message message; | |
116 | char slot_suffix[32]; | |
117 | char update_channel[128]; | |
118 | ||
0381b713 | 119 | // Round up the entire struct to 4096-byte. |
27d15611 AD |
120 | char reserved[1888]; |
121 | }; | |
122 | ||
123 | /** | |
124 | * Be cautious about the struct size change, in case we put anything post | |
125 | * bootloader_message_ab struct (b/29159185). | |
126 | */ | |
0381b713 | 127 | #ifndef __UBOOT__ |
27d15611 AD |
128 | #if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus) |
129 | static_assert(sizeof(struct bootloader_message_ab) == 4096, | |
130 | "struct bootloader_message_ab size changes"); | |
131 | #endif | |
0381b713 | 132 | #endif /* __UBOOT__ */ |
27d15611 AD |
133 | |
134 | #define BOOT_CTRL_MAGIC 0x42414342 /* Bootloader Control AB */ | |
135 | #define BOOT_CTRL_VERSION 1 | |
136 | ||
137 | struct slot_metadata { | |
0381b713 ER |
138 | // Slot priority with 15 meaning highest priority, 1 lowest |
139 | // priority and 0 the slot is unbootable. | |
27d15611 | 140 | uint8_t priority : 4; |
0381b713 | 141 | // Number of times left attempting to boot this slot. |
27d15611 | 142 | uint8_t tries_remaining : 3; |
0381b713 | 143 | // 1 if this slot has booted successfully, 0 otherwise. |
27d15611 | 144 | uint8_t successful_boot : 1; |
0381b713 ER |
145 | // 1 if this slot is corrupted from a dm-verity corruption, 0 |
146 | // otherwise. | |
27d15611 | 147 | uint8_t verity_corrupted : 1; |
0381b713 | 148 | // Reserved for further use. |
27d15611 AD |
149 | uint8_t reserved : 7; |
150 | } __attribute__((packed)); | |
151 | ||
152 | /* Bootloader Control AB | |
153 | * | |
154 | * This struct can be used to manage A/B metadata. It is designed to | |
155 | * be put in the 'slot_suffix' field of the 'bootloader_message' | |
156 | * structure described above. It is encouraged to use the | |
157 | * 'bootloader_control' structure to store the A/B metadata, but not | |
158 | * mandatory. | |
159 | */ | |
160 | struct bootloader_control { | |
0381b713 | 161 | // NUL terminated active slot suffix. |
27d15611 | 162 | char slot_suffix[4]; |
0381b713 | 163 | // Bootloader Control AB magic number (see BOOT_CTRL_MAGIC). |
27d15611 | 164 | uint32_t magic; |
0381b713 | 165 | // Version of struct being used (see BOOT_CTRL_VERSION). |
27d15611 | 166 | uint8_t version; |
0381b713 | 167 | // Number of slots being managed. |
27d15611 | 168 | uint8_t nb_slot : 3; |
0381b713 | 169 | // Number of times left attempting to boot recovery. |
27d15611 | 170 | uint8_t recovery_tries_remaining : 3; |
0381b713 | 171 | // Ensure 4-bytes alignment for slot_info field. |
27d15611 | 172 | uint8_t reserved0[2]; |
0381b713 | 173 | // Per-slot information. Up to 4 slots. |
27d15611 | 174 | struct slot_metadata slot_info[4]; |
0381b713 | 175 | // Reserved for further use. |
27d15611 | 176 | uint8_t reserved1[8]; |
0381b713 ER |
177 | // CRC32 of all 28 bytes preceding this field (little endian |
178 | // format). | |
27d15611 AD |
179 | uint32_t crc32_le; |
180 | } __attribute__((packed)); | |
181 | ||
0381b713 | 182 | #ifndef __UBOOT__ |
27d15611 AD |
183 | #if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus) |
184 | static_assert(sizeof(struct bootloader_control) == | |
185 | sizeof(((struct bootloader_message_ab *)0)->slot_suffix), | |
186 | "struct bootloader_control has wrong size"); | |
187 | #endif | |
0381b713 | 188 | #endif /* __UBOOT__ */ |
27d15611 AD |
189 | |
190 | #ifndef __UBOOT__ | |
27d15611 AD |
191 | #ifdef __cplusplus |
192 | ||
193 | #include <string> | |
194 | #include <vector> | |
195 | ||
0381b713 ER |
196 | // Return the block device name for the bootloader message partition and waits |
197 | // for the device for up to 10 seconds. In case of error returns the empty | |
198 | // string. | |
27d15611 AD |
199 | std::string get_bootloader_message_blk_device(std::string* err); |
200 | ||
0381b713 | 201 | // Read bootloader message into boot. Error message will be set in err. |
27d15611 AD |
202 | bool read_bootloader_message(bootloader_message* boot, std::string* err); |
203 | ||
0381b713 | 204 | // Read bootloader message from the specified misc device into boot. |
27d15611 AD |
205 | bool read_bootloader_message_from(bootloader_message* boot, const std::string& misc_blk_device, |
206 | std::string* err); | |
207 | ||
0381b713 | 208 | // Write bootloader message to BCB. |
27d15611 AD |
209 | bool write_bootloader_message(const bootloader_message& boot, std::string* err); |
210 | ||
0381b713 | 211 | // Write bootloader message to the specified BCB device. |
27d15611 AD |
212 | bool write_bootloader_message_to(const bootloader_message& boot, |
213 | const std::string& misc_blk_device, std::string* err); | |
214 | ||
0381b713 ER |
215 | // Write bootloader message (boots into recovery with the options) to BCB. Will |
216 | // set the command and recovery fields, and reset the rest. | |
27d15611 AD |
217 | bool write_bootloader_message(const std::vector<std::string>& options, std::string* err); |
218 | ||
0381b713 ER |
219 | // Write bootloader message (boots into recovery with the options) to the specific BCB device. Will |
220 | // set the command and recovery fields, and reset the rest. | |
27d15611 AD |
221 | bool write_bootloader_message_to(const std::vector<std::string>& options, |
222 | const std::string& misc_blk_device, std::string* err); | |
223 | ||
0381b713 ER |
224 | // Update bootloader message (boots into recovery with the options) to BCB. Will |
225 | // only update the command and recovery fields. | |
27d15611 AD |
226 | bool update_bootloader_message(const std::vector<std::string>& options, std::string* err); |
227 | ||
0381b713 ER |
228 | // Update bootloader message (boots into recovery with the |options|) in |boot|. Will only update |
229 | // the command and recovery fields. | |
27d15611 AD |
230 | bool update_bootloader_message_in_struct(bootloader_message* boot, |
231 | const std::vector<std::string>& options); | |
232 | ||
0381b713 | 233 | // Clear BCB. |
27d15611 AD |
234 | bool clear_bootloader_message(std::string* err); |
235 | ||
0381b713 | 236 | // Writes the reboot-bootloader reboot reason to the bootloader_message. |
27d15611 AD |
237 | bool write_reboot_bootloader(std::string* err); |
238 | ||
0381b713 | 239 | // Read the wipe package from BCB (from offset WIPE_PACKAGE_OFFSET_IN_MISC). |
27d15611 AD |
240 | bool read_wipe_package(std::string* package_data, size_t size, std::string* err); |
241 | ||
0381b713 | 242 | // Write the wipe package into BCB (to offset WIPE_PACKAGE_OFFSET_IN_MISC). |
27d15611 AD |
243 | bool write_wipe_package(const std::string& package_data, std::string* err); |
244 | ||
245 | #else | |
246 | ||
247 | #include <stdbool.h> | |
248 | ||
0381b713 | 249 | // C Interface. |
27d15611 AD |
250 | bool write_bootloader_message(const char* options); |
251 | bool write_reboot_bootloader(void); | |
252 | ||
0381b713 | 253 | #endif // ifdef __cplusplus |
27d15611 AD |
254 | #endif /* __UBOOT__ */ |
255 | ||
256 | #endif /* __ANDROID_BOOTLOADER_MESSAGE_H */ |