Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Side by Side Diff: utility/gbb_utility.cc

Issue 6173001: vboot_reference: add creation of GBB blob to gbb_utility (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/vboot_reference.git@master
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // Utility for manipulating Google Binary Block (GBB) 5 // Utility for manipulating Google Binary Block (GBB)
6 // 6 //
7 7
8 #include "gbb_utility.h" 8 #include "gbb_utility.h"
9 9
10 #include <assert.h> 10 #include <assert.h>
11 #include <getopt.h> 11 #include <getopt.h>
12 #include <stdio.h> 12 #include <stdio.h>
13 #include <stdlib.h>
13 #include <string.h> 14 #include <string.h>
14 15
15 #include <string> 16 #include <string>
16 #include <vector> 17 #include <vector>
17 #include <algorithm> 18 #include <algorithm>
18 19
19 using std::string; 20 using std::string;
20 21
21 /////////////////////////////////////////////////////////////////////// 22 ///////////////////////////////////////////////////////////////////////
22 // Simple File Utilities 23 // Simple File Utilities
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 // command line utilities 368 // command line utilities
368 369
369 #include <map> 370 #include <map>
370 371
371 using vboot_reference::GoogleBinaryBlockUtil; 372 using vboot_reference::GoogleBinaryBlockUtil;
372 373
373 // utility function: provide usage of this utility and exit. 374 // utility function: provide usage of this utility and exit.
374 static void usagehelp_exit(const char *prog_name) { 375 static void usagehelp_exit(const char *prog_name) {
375 printf( 376 printf(
376 "Utility to manage Google Binary Block (GBB)\n" 377 "Utility to manage Google Binary Block (GBB)\n"
377 "Usage: %s [-g|-s] [OPTIONS] bios_file [output_file]\n" 378 "Usage: %s [-g|-s|-c] [OPTIONS] bios_file [output_file]\n"
378 "\n" 379 "\n"
379 "GET MODE:\n" 380 "GET MODE:\n"
380 "-g, --get (default)\tGet (read) from bios_file, " 381 "-g, --get (default)\tGet (read) from bios_file, "
381 "with following options:\n" 382 "with following options:\n"
382 " --hwid \tReport hardware id (default).\n" 383 " --hwid \tReport hardware id (default).\n"
383 " -k, --rootkey=FILE \tFile name to export Root Key.\n" 384 " -k, --rootkey=FILE \tFile name to export Root Key.\n"
384 " -b, --bmpfv=FILE \tFile name to export Bitmap FV.\n" 385 " -b, --bmpfv=FILE \tFile name to export Bitmap FV.\n"
385 " --recoverykey=FILE\tFile name to export Recovery Key.\n" 386 " --recoverykey=FILE\tFile name to export Recovery Key.\n"
386 "\n" 387 "\n"
387 "SET MODE:\n" 388 "SET MODE:\n"
388 "-s, --set \tSet (write) to bios_file, " 389 "-s, --set \tSet (write) to bios_file, "
389 "with following options:\n" 390 "with following options:\n"
390 " -o, --output=FILE \tNew file name for ouptput.\n" 391 " -o, --output=FILE \tNew file name for ouptput.\n"
391 " -i, --hwid=HWID \tThe new hardware id to be changed.\n" 392 " -i, --hwid=HWID \tThe new hardware id to be changed.\n"
392 " -k, --rootkey=FILE \tFile name of new Root Key.\n" 393 " -k, --rootkey=FILE \tFile name of new Root Key.\n"
393 " -b, --bmpfv=FILE \tFile name of new Bitmap FV.\n" 394 " -b, --bmpfv=FILE \tFile name of new Bitmap FV.\n"
394 " --recoverykey=FILE\tFile name of new Recovery Key.\n" 395 " --recoverykey=FILE\tFile name of new Recovery Key.\n"
395 "\n" 396 "\n"
397 "CREATE MODE:\n"
398 "-c, --create=prop1_size,prop2_size...\n"
399 " \tCreate a GBB blob by given size list.\n"
396 "SAMPLE:\n" 400 "SAMPLE:\n"
397 " %s -g bios.bin\n" 401 " %s -g bios.bin\n"
398 " %s --set --hwid='New Model' -k key.bin bios.bin newbios.bin\n" 402 " %s --set --hwid='New Model' -k key.bin bios.bin newbios.bin\n"
399 , prog_name, prog_name, prog_name); 403 " %s -c 0x100,0x1000,0x03DE80,0x1000 gbb.blob\n"
404 , prog_name, prog_name, prog_name, prog_name);
400 exit(1); 405 exit(1);
401 } 406 }
402 407
403 // utility function: export a property from GBB to given file. 408 // utility function: export a property from GBB to given file.
404 // if filename was empty, export to console (screen). 409 // if filename was empty, export to console (screen).
405 // return true on success, otherwise false. 410 // return true on success, otherwise false.
406 static bool export_property(GoogleBinaryBlockUtil::PROPINDEX idx, 411 static bool export_property(GoogleBinaryBlockUtil::PROPINDEX idx,
407 const string &filename, 412 const string &filename,
408 const GoogleBinaryBlockUtil &util) { 413 const GoogleBinaryBlockUtil &util) {
409 string prop_name = util.get_property_name(idx), 414 string prop_name = util.get_property_name(idx),
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 printf(" - %s changed from '%s' to '%s': %s\n", 459 printf(" - %s changed from '%s' to '%s': %s\n",
455 prop_name.c_str(), old_value.c_str(), source.c_str(), 460 prop_name.c_str(), old_value.c_str(), source.c_str(),
456 result ? "success" : "failed"); 461 result ? "success" : "failed");
457 if (!result) 462 if (!result)
458 return false; 463 return false;
459 } 464 }
460 465
461 return true; 466 return true;
462 } 467 }
463 468
469 static bool parse_creation_param(const string &input_string,
470 std::vector<uint32_t> &output_vector) {
471 const char *input = input_string.c_str();
472 char *parsed = NULL;
473 uint32_t param;
474
475 do {
476 param = (uint32_t)strtol(input, &parsed, 0);
477 if (*parsed && *parsed != ',')
478 return false;
479 output_vector.push_back(param);
480 input = parsed + 1;
481 // printf("(debug) param: %zd\n", param);
482 } while(*input);
483
484 return true;
485 }
486
487 static string create_new_gbb(const std::vector<uint32_t> &create_param) {
Randall Spangler 2011/01/07 21:47:34 The current implementation of the GBB is done via
Hung-Te 2011/01/10 03:40:58 Done.
488 GoogleBinaryBlockHeader header = {0};
489 uint32_t *prop = &header.hwid_offset; // must be first entry.
490 uint32_t allocated_size = sizeof(header);
491 std::vector<uint32_t>::const_iterator i = create_param.begin();
492 string blob;
493
494 // max properties = available space in header / size of record (offset+size)
495 size_t max_properties =
496 (sizeof(header) - ((uint8_t*)prop - (uint8_t*)&header)) /
497 (sizeof(uint32_t) * 2);
498
499 if (create_param.size() >= max_properties) {
500 printf("error: creation parameters cannot exceed %zu entries.\n",
501 max_properties);
502 return blob;
503 }
504
505 memcpy(header.signature, GBB_SIGNATURE, GBB_SIGNATURE_SIZE);
506 header.major_version = GBB_MAJOR_VER;
507 header.minor_version = GBB_MINOR_VER;
508 header.header_size = GBB_HEADER_SIZE;
509
510 while (i != create_param.end()) {
511 *prop++ = allocated_size; // property offset
512 *prop++ = *i; // property size
513 allocated_size += *i;
514 i++;
515 }
516
517 blob.resize(allocated_size);
518 std::copy((char*)&header, (char*)(&header + 1), blob.begin());
519 return blob;
520 }
521
464 /////////////////////////////////////////////////////////////////////// 522 ///////////////////////////////////////////////////////////////////////
465 // main 523 // main
466 524
467 int main(int argc, char *argv[]) { 525 int main(int argc, char *argv[]) {
468 const char *myname = argv[0]; 526 const char *myname = argv[0];
469 int err_stage = 0; // an indicator for error exits 527 int err_stage = 0; // an indicator for error exits
470 528
471 // small parameter helper class 529 // small parameter helper class
472 class OptPropertyMap: public 530 class OptPropertyMap: public
473 std::map<GoogleBinaryBlockUtil::PROPINDEX, string> { 531 std::map<GoogleBinaryBlockUtil::PROPINDEX, string> {
474 public: 532 public:
475 bool set_new_value(GoogleBinaryBlockUtil::PROPINDEX id, const string &v) { 533 bool set_new_value(GoogleBinaryBlockUtil::PROPINDEX id, const string &v) {
476 if (find(id) != end()) 534 if (find(id) != end())
477 return false; 535 return false;
478 536
479 (*this)[id] = v; 537 (*this)[id] = v;
480 return true; 538 return true;
481 } 539 }
482 }; 540 };
483 OptPropertyMap opt_props; 541 OptPropertyMap opt_props;
484 542
485 struct GBBUtilOptions { 543 struct GBBUtilOptions {
486 bool get_mode, set_mode; 544 bool get_mode, set_mode, create_mode;
487 string input_fn, output_fn; 545 string input_fn, output_fn;
546 std::vector<uint32_t> create_param;
488 } myopts; 547 } myopts;
489 myopts.get_mode = myopts.set_mode = false; 548 myopts.get_mode = myopts.set_mode = false;
Che-Liang Chiou 2011/01/10 02:55:20 I'm not sure, but doesn't myopts.create_mode have
Hung-Te 2011/01/10 03:40:58 My bad. fixed.
490 549
491 // snippets for getopt_long 550 // snippets for getopt_long
492 int option_index, opt; 551 int option_index, opt;
493 static struct option long_options[] = { 552 static struct option long_options[] = {
494 {"get", 0, NULL, 'g' }, 553 {"get", 0, NULL, 'g' },
495 {"set", 0, NULL, 's' }, 554 {"set", 0, NULL, 's' },
555 {"create", 0, NULL, 'c' },
496 {"output", 1, NULL, 'o' }, 556 {"output", 1, NULL, 'o' },
497 {"hwid", 2, NULL, 'i' }, 557 {"hwid", 2, NULL, 'i' },
498 {"rootkey", 1, NULL, 'k' }, 558 {"rootkey", 1, NULL, 'k' },
499 {"bmpfv", 1, NULL, 'b' }, 559 {"bmpfv", 1, NULL, 'b' },
500 {"recoverykey", 1, NULL, 'R' }, 560 {"recoverykey", 1, NULL, 'R' },
501 { NULL, 0, NULL, 0 }, 561 { NULL, 0, NULL, 0 },
502 }; 562 };
503 563
504 // parse command line options 564 // parse command line options
505 while ((opt = getopt_long(argc, argv, "gso:i:k:b:", 565 while ((opt = getopt_long(argc, argv, "gsc:o:i:k:b:",
506 long_options, &option_index)) >= 0) { 566 long_options, &option_index)) >= 0) {
507 switch (opt) { 567 switch (opt) {
508 case 'g': 568 case 'g':
509 myopts.get_mode = true; 569 myopts.get_mode = true;
510 break; 570 break;
511 571
512 case 's': 572 case 's':
513 myopts.set_mode = true; 573 myopts.set_mode = true;
514 break; 574 break;
515 575
576 case 'c':
577 myopts.create_mode = true;
578 {
579 const char *param = optarg ? optarg : "(empty)";
580 if (!parse_creation_param(param, myopts.create_param)) {
Che-Liang Chiou 2011/01/10 02:55:20 Isn't this equivalent to "if (!optarg || !parse_cr
Hung-Te 2011/01/10 03:40:58 Because in that case I need to put something in er
581 printf("error: invalid creation parameter: %s\n", param);
582 usagehelp_exit(myname);
583 }
584 }
585 break;
586
516 case 'o': 587 case 'o':
517 myopts.output_fn = optarg; 588 myopts.output_fn = optarg;
518 break; 589 break;
519 590
520 case 'i': 591 case 'i':
521 if (!opt_props.set_new_value( 592 if (!opt_props.set_new_value(
522 GoogleBinaryBlockUtil::PROP_HWID, optarg ? optarg : "")) 593 GoogleBinaryBlockUtil::PROP_HWID, optarg ? optarg : ""))
523 usagehelp_exit(myname); 594 usagehelp_exit(myname);
524 break; 595 break;
525 596
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 629
559 // currently, the only parameter is 'input file'. 630 // currently, the only parameter is 'input file'.
560 if (argc == 1) { 631 if (argc == 1) {
561 myopts.input_fn = argv[0]; 632 myopts.input_fn = argv[0];
562 } else { 633 } else {
563 usagehelp_exit(myname); 634 usagehelp_exit(myname);
564 } 635 }
565 636
566 // stage: complete parameter parsing and checking 637 // stage: complete parameter parsing and checking
567 err_stage++; 638 err_stage++;
568 if (myopts.get_mode == myopts.set_mode) { 639 if (myopts.create_mode) {
640 if (myopts.get_mode || myopts.set_mode) {
641 printf("error: please assign only one mode from get/set/create.\n");
642 return err_stage;
643 }
644 if (!opt_props.empty() || myopts.create_param.empty()) {
645 printf("error: creation parameter syntax error.\n");
646 return err_stage;
647 }
648 if (myopts.output_fn.empty()) {
649 myopts.output_fn = myopts.input_fn;
650 }
651 } else if (myopts.get_mode == myopts.set_mode) {
569 if (myopts.get_mode) { 652 if (myopts.get_mode) {
570 printf("error: please assign either get or set mode.\n"); 653 printf("error: please assign either get or set mode.\n");
571 return err_stage; 654 return err_stage;
572 } else { 655 } else {
573 // enter 'get' mode by default, if not assigned. 656 // enter 'get' mode by default, if not assigned.
574 myopts.get_mode = true; 657 myopts.get_mode = true;
575 } 658 }
576 } 659 }
577 if (myopts.get_mode && !myopts.output_fn.empty()) { 660 if (myopts.get_mode && !myopts.output_fn.empty()) {
578 printf("error: get-mode does not create output files.\n"); 661 printf("error: get-mode does not create output files.\n");
579 return err_stage; 662 return err_stage;
580 } 663 }
581 664
665 if (myopts.create_mode) {
666 // creation is not handled by GoogleBinaryBlockUtil.
667 string blob = create_new_gbb(myopts.create_param);
668
669 if (blob.empty())
670 return err_stage;
671
672 if (!write_nonempty_file(myopts.output_fn.c_str(), blob)) {
673 printf("error: cannot create to file: %s\n", myopts.output_fn.c_str());
674 return err_stage;
675 } else {
676 printf("successfully created new GBB to: %s\n", myopts.output_fn.c_str());
677 }
678 return 0;
679 }
680
582 // stage: load image files 681 // stage: load image files
583 err_stage++; 682 err_stage++;
584 GoogleBinaryBlockUtil util; 683 GoogleBinaryBlockUtil util;
585 684
586 assert(!myopts.input_fn.empty()); 685 assert(!myopts.input_fn.empty());
587 if (!util.load_from_file(myopts.input_fn.c_str())) { 686 if (!util.load_from_file(myopts.input_fn.c_str())) {
588 printf("error: cannot load valid BIOS file: %s\n", myopts.input_fn.c_str()); 687 printf("error: cannot load valid BIOS file: %s\n", myopts.input_fn.c_str());
589 return err_stage; 688 return err_stage;
590 } 689 }
591 690
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 return err_stage; 738 return err_stage;
640 } else { 739 } else {
641 printf("successfully saved new image to: %s\n", myopts.output_fn.c_str()); 740 printf("successfully saved new image to: %s\n", myopts.output_fn.c_str());
642 } 741 }
643 } 742 }
644 743
645 return 0; 744 return 0;
646 } 745 }
647 746
648 #endif // WITH_UTIL_MAIN 747 #endif // WITH_UTIL_MAIN
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698