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

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: fix lint warnings 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 | utility/include/gbb_utility.h » ('j') | 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 } 87 }
87 88
88 void GoogleBinaryBlockUtil::initialize() { 89 void GoogleBinaryBlockUtil::initialize() {
89 verbose = true; 90 verbose = true;
90 is_valid_gbb = false; 91 is_valid_gbb = false;
91 header_offset_ = 0; 92 header_offset_ = 0;
92 memset(&header_, 0, sizeof(header_)); 93 memset(&header_, 0, sizeof(header_));
93 file_content_.clear(); 94 file_content_.clear();
94 } 95 }
95 96
97 bool GoogleBinaryBlockUtil::create_new(
98 const std::vector<uint32_t> &create_param) {
99 uint32_t *prop = &header_.hwid_offset; // must be first entry.
100 uint32_t allocated_size = sizeof(header_);
101 std::vector<uint32_t>::const_iterator i = create_param.begin();
102
103 // max properties = available space in header / size of record (offset+size)
104 size_t max_properties =
105 (sizeof(header_) - (reinterpret_cast<uint8_t*>(prop) -
106 reinterpret_cast<uint8_t*>(&header_))) /
107 (sizeof(uint32_t) * 2);
108
109 if (create_param.size() >= max_properties) {
110 if (verbose)
111 fprintf(stderr, "error: creation parameters cannot exceed %zu entries.\n",
112 max_properties);
113 return false;
114 }
115
116 initialize();
117 memcpy(header_.signature, GBB_SIGNATURE, GBB_SIGNATURE_SIZE);
118 header_.major_version = GBB_MAJOR_VER;
119 header_.minor_version = GBB_MINOR_VER;
120 header_.header_size = GBB_HEADER_SIZE;
121
122 while (i != create_param.end()) {
123 *prop++ = allocated_size; // property offset
124 *prop++ = *i; // property size
125 allocated_size += *i;
126 i++;
127 }
128
129 file_content_.resize(allocated_size);
130 std::copy(reinterpret_cast<char*>(&header_),
131 reinterpret_cast<char*>(&header_ + 1),
132 file_content_.begin());
133 is_valid_gbb = true;
134 return true;
135 }
136
137
96 bool GoogleBinaryBlockUtil::load_from_file(const char *filename) { 138 bool GoogleBinaryBlockUtil::load_from_file(const char *filename) {
97 is_valid_gbb = false; 139 is_valid_gbb = false;
98 140
99 file_content_ = read_nonempty_file(filename); 141 file_content_ = read_nonempty_file(filename);
100 if (file_content_.empty()) 142 if (file_content_.empty())
101 return false; 143 return false;
102 144
103 switch (search_header_signatures(file_content_, &header_offset_)) { 145 switch (search_header_signatures(file_content_, &header_offset_)) {
104 case 0: 146 case 0:
105 if (verbose) 147 if (verbose)
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 // command line utilities 409 // command line utilities
368 410
369 #include <map> 411 #include <map>
370 412
371 using vboot_reference::GoogleBinaryBlockUtil; 413 using vboot_reference::GoogleBinaryBlockUtil;
372 414
373 // utility function: provide usage of this utility and exit. 415 // utility function: provide usage of this utility and exit.
374 static void usagehelp_exit(const char *prog_name) { 416 static void usagehelp_exit(const char *prog_name) {
375 printf( 417 printf(
376 "Utility to manage Google Binary Block (GBB)\n" 418 "Utility to manage Google Binary Block (GBB)\n"
377 "Usage: %s [-g|-s] [OPTIONS] bios_file [output_file]\n" 419 "Usage: %s [-g|-s|-c] [OPTIONS] bios_file [output_file]\n"
378 "\n" 420 "\n"
379 "GET MODE:\n" 421 "GET MODE:\n"
380 "-g, --get (default)\tGet (read) from bios_file, " 422 "-g, --get (default)\tGet (read) from bios_file, "
381 "with following options:\n" 423 "with following options:\n"
382 " --hwid \tReport hardware id (default).\n" 424 " --hwid \tReport hardware id (default).\n"
383 " -k, --rootkey=FILE \tFile name to export Root Key.\n" 425 " -k, --rootkey=FILE \tFile name to export Root Key.\n"
384 " -b, --bmpfv=FILE \tFile name to export Bitmap FV.\n" 426 " -b, --bmpfv=FILE \tFile name to export Bitmap FV.\n"
385 " --recoverykey=FILE\tFile name to export Recovery Key.\n" 427 " --recoverykey=FILE\tFile name to export Recovery Key.\n"
386 "\n" 428 "\n"
387 "SET MODE:\n" 429 "SET MODE:\n"
388 "-s, --set \tSet (write) to bios_file, " 430 "-s, --set \tSet (write) to bios_file, "
389 "with following options:\n" 431 "with following options:\n"
390 " -o, --output=FILE \tNew file name for ouptput.\n" 432 " -o, --output=FILE \tNew file name for ouptput.\n"
391 " -i, --hwid=HWID \tThe new hardware id to be changed.\n" 433 " -i, --hwid=HWID \tThe new hardware id to be changed.\n"
392 " -k, --rootkey=FILE \tFile name of new Root Key.\n" 434 " -k, --rootkey=FILE \tFile name of new Root Key.\n"
393 " -b, --bmpfv=FILE \tFile name of new Bitmap FV.\n" 435 " -b, --bmpfv=FILE \tFile name of new Bitmap FV.\n"
394 " --recoverykey=FILE\tFile name of new Recovery Key.\n" 436 " --recoverykey=FILE\tFile name of new Recovery Key.\n"
395 "\n" 437 "\n"
438 "CREATE MODE:\n"
439 "-c, --create=prop1_size,prop2_size...\n"
440 " \tCreate a GBB blob by given size list.\n"
396 "SAMPLE:\n" 441 "SAMPLE:\n"
397 " %s -g bios.bin\n" 442 " %s -g bios.bin\n"
398 " %s --set --hwid='New Model' -k key.bin bios.bin newbios.bin\n" 443 " %s --set --hwid='New Model' -k key.bin bios.bin newbios.bin\n"
399 , prog_name, prog_name, prog_name); 444 " %s -c 0x100,0x1000,0x03DE80,0x1000 gbb.blob\n"
445 , prog_name, prog_name, prog_name, prog_name);
400 exit(1); 446 exit(1);
401 } 447 }
402 448
403 // utility function: export a property from GBB to given file. 449 // utility function: export a property from GBB to given file.
404 // if filename was empty, export to console (screen). 450 // if filename was empty, export to console (screen).
405 // return true on success, otherwise false. 451 // return true on success, otherwise false.
406 static bool export_property(GoogleBinaryBlockUtil::PROPINDEX idx, 452 static bool export_property(GoogleBinaryBlockUtil::PROPINDEX idx,
407 const string &filename, 453 const string &filename,
408 const GoogleBinaryBlockUtil &util) { 454 const GoogleBinaryBlockUtil &util) {
409 string prop_name = util.get_property_name(idx), 455 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", 500 printf(" - %s changed from '%s' to '%s': %s\n",
455 prop_name.c_str(), old_value.c_str(), source.c_str(), 501 prop_name.c_str(), old_value.c_str(), source.c_str(),
456 result ? "success" : "failed"); 502 result ? "success" : "failed");
457 if (!result) 503 if (!result)
458 return false; 504 return false;
459 } 505 }
460 506
461 return true; 507 return true;
462 } 508 }
463 509
510 static bool parse_creation_param(const string &input_string,
511 std::vector<uint32_t> *output_vector) {
512 const char *input = input_string.c_str();
513 char *parsed = NULL;
514 uint32_t param;
515
516 if (input_string.empty())
517 return false;
518
519 do {
520 param = (uint32_t)strtol(input, &parsed, 0);
521 if (*parsed && *parsed != ',')
522 return false;
523 output_vector->push_back(param);
524 input = parsed + 1;
525 // printf("(debug) param: %zd\n", param);
526 } while (*input);
527
528 return true;
529 }
530
464 /////////////////////////////////////////////////////////////////////// 531 ///////////////////////////////////////////////////////////////////////
465 // main 532 // main
466 533
467 int main(int argc, char *argv[]) { 534 int main(int argc, char *argv[]) {
468 const char *myname = argv[0]; 535 const char *myname = argv[0];
469 int err_stage = 0; // an indicator for error exits 536 int err_stage = 0; // an indicator for error exits
537 GoogleBinaryBlockUtil util;
470 538
471 // small parameter helper class 539 // small parameter helper class
472 class OptPropertyMap: public 540 class OptPropertyMap: public
473 std::map<GoogleBinaryBlockUtil::PROPINDEX, string> { 541 std::map<GoogleBinaryBlockUtil::PROPINDEX, string> {
474 public: 542 public:
475 bool set_new_value(GoogleBinaryBlockUtil::PROPINDEX id, const string &v) { 543 bool set_new_value(GoogleBinaryBlockUtil::PROPINDEX id, const string &v) {
476 if (find(id) != end()) 544 if (find(id) != end())
477 return false; 545 return false;
478 546
479 (*this)[id] = v; 547 (*this)[id] = v;
480 return true; 548 return true;
481 } 549 }
482 }; 550 };
483 OptPropertyMap opt_props; 551 OptPropertyMap opt_props;
484 552
485 struct GBBUtilOptions { 553 struct GBBUtilOptions {
486 bool get_mode, set_mode; 554 bool get_mode, set_mode, create_mode;
487 string input_fn, output_fn; 555 string input_fn, output_fn;
556 std::vector<uint32_t> create_param;
488 } myopts; 557 } myopts;
489 myopts.get_mode = myopts.set_mode = false; 558 myopts.get_mode = myopts.set_mode = myopts.create_mode = false;
490 559
491 // snippets for getopt_long 560 // snippets for getopt_long
492 int option_index, opt; 561 int option_index, opt;
493 static struct option long_options[] = { 562 static struct option long_options[] = {
494 {"get", 0, NULL, 'g' }, 563 {"get", 0, NULL, 'g' },
495 {"set", 0, NULL, 's' }, 564 {"set", 0, NULL, 's' },
565 {"create", 1, NULL, 'c' },
496 {"output", 1, NULL, 'o' }, 566 {"output", 1, NULL, 'o' },
497 {"hwid", 2, NULL, 'i' }, 567 {"hwid", 2, NULL, 'i' },
498 {"rootkey", 1, NULL, 'k' }, 568 {"rootkey", 1, NULL, 'k' },
499 {"bmpfv", 1, NULL, 'b' }, 569 {"bmpfv", 1, NULL, 'b' },
500 {"recoverykey", 1, NULL, 'R' }, 570 {"recoverykey", 1, NULL, 'R' },
501 { NULL, 0, NULL, 0 }, 571 { NULL, 0, NULL, 0 },
502 }; 572 };
503 573
504 // parse command line options 574 // parse command line options
505 while ((opt = getopt_long(argc, argv, "gso:i:k:b:", 575 while ((opt = getopt_long(argc, argv, "gsc:o:i:k:b:",
506 long_options, &option_index)) >= 0) { 576 long_options, &option_index)) >= 0) {
507 switch (opt) { 577 switch (opt) {
508 case 'g': 578 case 'g':
509 myopts.get_mode = true; 579 myopts.get_mode = true;
510 break; 580 break;
511 581
512 case 's': 582 case 's':
513 myopts.set_mode = true; 583 myopts.set_mode = true;
514 break; 584 break;
515 585
586 case 'c':
587 myopts.create_mode = true;
588 assert(optarg);
589 if (!*optarg || !parse_creation_param(optarg, &myopts.create_param)) {
590 printf("error: invalid creation parameter: %s\n", optarg);
591 usagehelp_exit(myname);
592 }
593 break;
594
516 case 'o': 595 case 'o':
517 myopts.output_fn = optarg; 596 myopts.output_fn = optarg;
518 break; 597 break;
519 598
520 case 'i': 599 case 'i':
521 if (!opt_props.set_new_value( 600 if (!opt_props.set_new_value(
522 GoogleBinaryBlockUtil::PROP_HWID, optarg ? optarg : "")) 601 GoogleBinaryBlockUtil::PROP_HWID, optarg ? optarg : ""))
523 usagehelp_exit(myname); 602 usagehelp_exit(myname);
524 break; 603 break;
525 604
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 637
559 // currently, the only parameter is 'input file'. 638 // currently, the only parameter is 'input file'.
560 if (argc == 1) { 639 if (argc == 1) {
561 myopts.input_fn = argv[0]; 640 myopts.input_fn = argv[0];
562 } else { 641 } else {
563 usagehelp_exit(myname); 642 usagehelp_exit(myname);
564 } 643 }
565 644
566 // stage: complete parameter parsing and checking 645 // stage: complete parameter parsing and checking
567 err_stage++; 646 err_stage++;
568 if (myopts.get_mode == myopts.set_mode) { 647 if (myopts.create_mode) {
648 if (myopts.get_mode || myopts.set_mode) {
649 printf("error: please assign only one mode from get/set/create.\n");
650 return err_stage;
651 }
652 if (!opt_props.empty() || myopts.create_param.empty()) {
653 printf("error: creation parameter syntax error.\n");
654 return err_stage;
655 }
656 if (myopts.output_fn.empty()) {
657 myopts.output_fn = myopts.input_fn;
658 }
659 } else if (myopts.get_mode == myopts.set_mode) {
569 if (myopts.get_mode) { 660 if (myopts.get_mode) {
570 printf("error: please assign either get or set mode.\n"); 661 printf("error: please assign either get or set mode.\n");
571 return err_stage; 662 return err_stage;
572 } else { 663 } else {
573 // enter 'get' mode by default, if not assigned. 664 // enter 'get' mode by default, if not assigned.
574 myopts.get_mode = true; 665 myopts.get_mode = true;
575 } 666 }
576 } 667 }
577 if (myopts.get_mode && !myopts.output_fn.empty()) { 668 if (myopts.get_mode && !myopts.output_fn.empty()) {
578 printf("error: get-mode does not create output files.\n"); 669 printf("error: get-mode does not create output files.\n");
579 return err_stage; 670 return err_stage;
580 } 671 }
581 672
673 if (myopts.create_mode) {
674 if (!util.create_new(myopts.create_param))
675 return err_stage;
676
677 assert(!myopts.output_fn.empty());
678 if (!util.save_to_file(myopts.output_fn.c_str())) {
679 printf("error: cannot create to file: %s\n", myopts.output_fn.c_str());
680 return err_stage;
681 } else {
682 printf("successfully created new GBB to: %s\n", myopts.output_fn.c_str());
683 }
684 return 0;
685 }
686
582 // stage: load image files 687 // stage: load image files
583 err_stage++; 688 err_stage++;
584 GoogleBinaryBlockUtil util;
585
586 assert(!myopts.input_fn.empty()); 689 assert(!myopts.input_fn.empty());
587 if (!util.load_from_file(myopts.input_fn.c_str())) { 690 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()); 691 printf("error: cannot load valid BIOS file: %s\n", myopts.input_fn.c_str());
589 return err_stage; 692 return err_stage;
590 } 693 }
591 694
592 // stage: processing by mode 695 // stage: processing by mode
593 err_stage++; 696 err_stage++;
594 if (myopts.get_mode) { 697 if (myopts.get_mode) {
595 // get mode 698 // get mode
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 return err_stage; 742 return err_stage;
640 } else { 743 } else {
641 printf("successfully saved new image to: %s\n", myopts.output_fn.c_str()); 744 printf("successfully saved new image to: %s\n", myopts.output_fn.c_str());
642 } 745 }
643 } 746 }
644 747
645 return 0; 748 return 0;
646 } 749 }
647 750
648 #endif // WITH_UTIL_MAIN 751 #endif // WITH_UTIL_MAIN
OLDNEW
« no previous file with comments | « no previous file | utility/include/gbb_utility.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698