1 /* Copyright 2018 The ChromiumOS Authors
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * The command line tool to invoke firmware updater.
6 */
7
8 #include <assert.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <getopt.h>
12
13 #include "futility.h"
14 #include "updater.h"
15
16 #ifdef USE_FLASHROM
17
18 enum {
19 OPT_DUMMY = 0x1000,
20 OPT_DETECT_MODEL_ONLY,
21 OPT_FACTORY,
22 OPT_FAST,
23 OPT_FORCE,
24 OPT_GBB_FLAGS,
25 OPT_HOST_ONLY,
26 OPT_MANIFEST,
27 OPT_MODEL,
28 OPT_OUTPUT_DIR,
29 OPT_QUIRKS,
30 OPT_QUIRKS_LIST,
31 OPT_REPACK,
32 OPT_SERVO_NORESET,
33 OPT_SIGNATURE,
34 OPT_SYS_PROPS,
35 OPT_UNLOCK_ME,
36 OPT_UNPACK,
37 OPT_WRITE_PROTECTION,
38 };
39
40 /* Command line options */
41 static struct option const long_opts[] = {
42 SHARED_FLASH_ARGS_LONGOPTS
43 /* name has_arg *flag val */
44 {"help", 0, NULL, 'h'},
45 {"debug", 0, NULL, 'd'},
46 {"verbose", 0, NULL, 'v'},
47
48 {"image", 1, NULL, 'i'},
49 {"ec_image", 1, NULL, 'e'},
50 {"try", 0, NULL, 't'},
51 {"archive", 1, NULL, 'a'},
52 {"mode", 1, NULL, 'm'},
53
54 {"detect-model-only", 0, NULL, OPT_DETECT_MODEL_ONLY},
55 {"factory", 0, NULL, OPT_FACTORY},
56 {"fast", 0, NULL, OPT_FAST},
57 {"force", 0, NULL, OPT_FORCE},
58 {"gbb_flags", 1, NULL, OPT_GBB_FLAGS},
59 {"host_only", 0, NULL, OPT_HOST_ONLY},
60 {"quirks", 1, NULL, OPT_QUIRKS},
61 {"list-quirks", 0, NULL, OPT_QUIRKS_LIST},
62 {"manifest", 0, NULL, OPT_MANIFEST},
63 {"model", 1, NULL, OPT_MODEL},
64 {"output_dir", 1, NULL, OPT_OUTPUT_DIR},
65 {"repack", 1, NULL, OPT_REPACK},
66 {"signature_id", 1, NULL, OPT_SIGNATURE},
67 {"sys_props", 1, NULL, OPT_SYS_PROPS},
68 {"unlock_me", 0, NULL, OPT_UNLOCK_ME},
69 {"unpack", 1, NULL, OPT_UNPACK},
70 {"wp", 1, NULL, OPT_WRITE_PROTECTION},
71
72 /* TODO(hungte) Remove following deprecated options. */
73 {"noupdate_ec", 0, NULL, OPT_HOST_ONLY},
74 {"nocheck_keys", 0, NULL, OPT_FORCE},
75 {"update_main", 0, NULL, OPT_DUMMY},
76 {"update_ec", 0, NULL, OPT_DUMMY},
77 {"check_keys", 0, NULL, OPT_DUMMY},
78
79 {NULL, 0, NULL, 0},
80 };
81
82 static const char *const short_opts =
83 "hdvi:e:ta:m:" SHARED_FLASH_ARGS_SHORTOPTS;
84
print_help(int argc,char * argv[])85 static void print_help(int argc, char *argv[])
86 {
87 printf("\n"
88 "Usage: " MYNAME " %s [OPTIONS]\n"
89 "\n"
90 "Updates firmware in one of the following modes (default to recovery):\n"
91 " autoupdate:\tUpdate RW[A|B], or recovery if RO changed.\n"
92 " recovery: \tUpdate RW[A&B], (RO, RO:GBB[keys] - if RO changed)\n"
93 " factory: \tUpdate RW[A&B], RO, RO:GBB[keys,flags]\n"
94 "\n"
95 "Note: firmware sections with PRESERVE flags like VPD and\n"
96 " HWID in GBB are always preserved.\n"
97 " GBB flags are preserved in autoupdate and recovery modes.\n"
98 "\n"
99 "OPTIONS:\n"
100 "\n"
101 "-i, --image=FILE \tAP (host) firmware image (image.bin)\n"
102 "-e, --ec_image=FILE \tEC firmware image (i.e, ec.bin)\n"
103 "-t, --try \tTry A/B update on reboot if possible\n"
104 "-a, --archive=PATH \tRead resources from archive\n"
105 " --unpack=DIR \tExtracts archive to DIR\n"
106 " --fast \tReduce read cycles and do not verify\n"
107 " --quirks=LIST \tSpecify the quirks to apply\n"
108 " --list-quirks \tPrint all available quirks\n"
109 "-m, --mode=MODE \tRun updater in the specified mode\n"
110 " --manifest \tScan the archive to print a manifest in JSON\n"
111 SHARED_FLASH_ARGS_HELP
112 "\n"
113 " * Option --manifest requires either -a,--archive or -i,--image\n"
114 " With -i,--image additional images are accepted with options\n"
115 " -e,--ec_image.\n"
116 " * If both --manifest and --fast are specified, the updater\n"
117 " will not scan the archive and simply dump the previously\n"
118 " cached manifest (may be out-dated) from the archive.\n"
119 " Works only with -a,--archive option.\n"
120 " * Use of -p,--programmer with option other than '%s',\n"
121 " or with --ccd effectively disables ability to update EC\n"
122 " firmware images.\n"
123 " * Emulation works only with the AP (host) firmware image, and\n"
124 " does not support the EC firmware image.\n"
125 " * Model detection with option --detect-model-only requires\n"
126 " archive path -a,--archive\n"
127 " * The --quirks provides a set of options to override the\n"
128 " default behavior. Run --list-quirks to get the options,\n"
129 " and --quirks OPTION to turn on. To disable a quirk that\n"
130 " was default turned on from the firmware image CBFS, do\n"
131 " --quirks OPTION=0 to turn off.\n"
132 "\n"
133 "Legacy and compatibility options:\n"
134 " --factory \tAlias for --mode=factory\n"
135 " --force \tForce update (skip checking contents)\n"
136 " --output_dir=DIR\tSpecify the target for --mode=output\n"
137 " --unlock_me \t(deprecated) Unlock the Intel ME before flashing\n"
138 " --signature_id=S\t(deprecated) Same as --model\n"
139 "\n"
140 "Debugging and testing options:\n"
141 " --wp=1|0 \tSpecify write protection status\n"
142 " --host_only \tUpdate only AP (host) firmware\n"
143 " --model=MODEL \tOverride system model for images\n"
144 " --detect-model-only\tDetect model by reading the FRID and exit\n"
145 " --gbb_flags=FLAG\tOverride new GBB flags\n"
146 " --sys_props=LIST\tList of system properties to override\n"
147 "-d, --debug \tPrint debugging messages\n"
148 "-v, --verbose \tPrint verbose messages\n"
149 "",
150 argv[0], FLASHROM_PROGRAMMER_INTERNAL_AP);
151 }
152
do_update(int argc,char * argv[])153 static int do_update(int argc, char *argv[])
154 {
155 struct updater_config_arguments args = {0};
156 int i, errorcnt = 0;
157 const char *prepare_ctrl_name = NULL;
158 char *servo_programmer = NULL;
159 char *endptr;
160 const char *sig = NULL;
161
162 struct updater_config *cfg = updater_new_config();
163 assert(cfg);
164
165 opterr = 0;
166 while ((i = getopt_long(argc, argv, short_opts, long_opts, 0)) != -1) {
167 if (handle_flash_argument(&args, i, optarg))
168 continue;
169 switch (i) {
170 case 'h':
171 print_help(argc, argv);
172 updater_delete_config(cfg);
173 return !!errorcnt;
174 case 'd':
175 debugging_enabled = 1;
176 args.verbosity++;
177 break;
178 case 'v':
179 args.verbosity++;
180 break;
181 case 'i':
182 args.image = optarg;
183 break;
184 case 'e':
185 args.ec_image = optarg;
186 break;
187 case 't':
188 args.try_update = 1;
189 break;
190 case 'a':
191 args.archive = optarg;
192 break;
193 case 'm':
194 args.mode = optarg;
195 break;
196
197 case OPT_REPACK:
198 args.repack = optarg;
199 ERROR("Sorry, --repack is only for the script.\n");
200 errorcnt ++;
201 break;
202 case OPT_UNPACK:
203 args.unpack = optarg;
204 break;
205 case OPT_UNLOCK_ME:
206 WARN("--unlock_me will be deprecated by --quirks unlock_csme.\n");
207 args.unlock_me = true;
208 break;
209 case OPT_QUIRKS:
210 args.quirks = optarg;
211 break;
212 case OPT_QUIRKS_LIST:
213 updater_list_config_quirks(cfg);
214 updater_delete_config(cfg);
215 return 0;
216 case OPT_OUTPUT_DIR:
217 args.output_dir = optarg;
218 break;
219 case OPT_MODEL:
220 if (sig) {
221 WARN("Ignore --model=%s because --signature_id=%s is already specified.\n", optarg, sig);
222 } else {
223 args.model = optarg;
224 }
225 break;
226 case OPT_SIGNATURE:
227 WARN("--signature_id is deprecated by --model. "
228 "Please change to `--model=%s` in future.\n",
229 optarg);
230 sig = optarg;
231 args.model = optarg;
232 break;
233 case OPT_DETECT_MODEL_ONLY:
234 args.detect_model_only = true;
235 break;
236 case OPT_WRITE_PROTECTION:
237 args.write_protection = optarg;
238 break;
239 case OPT_SYS_PROPS:
240 args.sys_props = optarg;
241 break;
242 case OPT_MANIFEST:
243 args.do_manifest = 1;
244 break;
245 case OPT_FACTORY:
246 args.is_factory = 1;
247 break;
248 case OPT_HOST_ONLY:
249 args.host_only = 1;
250 break;
251 case OPT_FORCE:
252 args.force_update = 1;
253 break;
254 case OPT_FAST:
255 args.fast_update = 1;
256 break;
257 case OPT_GBB_FLAGS:
258 args.gbb_flags = strtoul(optarg, &endptr, 0);
259 if (*endptr) {
260 ERROR("Invalid flags: %s\n", optarg);
261 errorcnt++;
262 } else {
263 args.override_gbb_flags = 1;
264 }
265 break;
266 case OPT_DUMMY:
267 break;
268
269 case '?':
270 errorcnt++;
271 if (optopt)
272 ERROR("Unrecognized option: -%c\n", optopt);
273 else if (argv[optind - 1])
274 ERROR("Unrecognized option (possibly '%s')\n",
275 argv[optind - 1]);
276 else
277 ERROR("Unrecognized option.\n");
278 break;
279 default:
280 errorcnt++;
281 ERROR("Failed parsing options.\n");
282 }
283 }
284 if (optind < argc) {
285 errorcnt++;
286 ERROR("Unexpected arguments.\n");
287 }
288
289 if (!errorcnt && args.detect_servo) {
290 servo_programmer = host_detect_servo(&prepare_ctrl_name);
291
292 if (!servo_programmer)
293 errorcnt++;
294 else if (!args.programmer)
295 args.programmer = servo_programmer;
296 }
297 /*
298 * Some boards may need to fetch firmware before starting to
299 * update (i.e., in updater_setup_config) so we want to turn on
300 * cpu_fw_spi mode now.
301 */
302 prepare_servo_control(prepare_ctrl_name, true);
303
304 const bool update_needed = updater_should_update(&args);
305 if (!errorcnt)
306 errorcnt += updater_setup_config(cfg, &args);
307 if (!errorcnt && update_needed) {
308 int r;
309 STATUS("Starting firmware updater.\n");
310 r = update_firmware(cfg);
311 if (r != UPDATE_ERR_DONE) {
312 r = VB2_MIN(r, UPDATE_ERR_UNKNOWN);
313 ERROR("%s\n", updater_error_messages[r]);
314 errorcnt++;
315 }
316 /* Use stdout for the final result. */
317 printf(">> %s: Firmware updater %s.\n",
318 errorcnt ? "FAILED": "DONE",
319 errorcnt ? "aborted" : "exits successfully");
320 }
321
322 prepare_servo_control(prepare_ctrl_name, false);
323 free(servo_programmer);
324
325 updater_delete_config(cfg);
326 return !!errorcnt;
327 }
328 #define CMD_HELP_STR "Update system firmware"
329
330 #else /* USE_FLASHROM */
331
do_update(int argc,char * argv[])332 static int do_update(int argc, char *argv[])
333 {
334 FATAL(MYNAME " was built without flashrom support, `update` command unavailable!\n");
335 return -1;
336 }
337 #define CMD_HELP_STR "Update system firmware (unavailable in this build)"
338
339 #endif /* !USE_FLASHROM */
340
341 DECLARE_FUTIL_COMMAND(update, do_update, VBOOT_VERSION_ALL, CMD_HELP_STR);
342