OLD | NEW |
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 * Verified boot kernel utility | 5 * Verified boot kernel utility |
6 */ | 6 */ |
7 | 7 |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <getopt.h> | 9 #include <getopt.h> |
10 #include <inttypes.h> /* For PRIu64 */ | 10 #include <inttypes.h> /* For PRIu64 */ |
(...skipping 17 matching lines...) Expand all Loading... |
28 | 28 |
29 static const int DEFAULT_PADDING = 65536; | 29 static const int DEFAULT_PADDING = 65536; |
30 | 30 |
31 /* Command line options */ | 31 /* Command line options */ |
32 enum { | 32 enum { |
33 OPT_MODE_PACK = 1000, | 33 OPT_MODE_PACK = 1000, |
34 OPT_MODE_REPACK, | 34 OPT_MODE_REPACK, |
35 OPT_MODE_VERIFY, | 35 OPT_MODE_VERIFY, |
36 OPT_ARCH, | 36 OPT_ARCH, |
37 OPT_OLDBLOB, | 37 OPT_OLDBLOB, |
| 38 OPT_KLOADADDR, |
38 OPT_KEYBLOCK, | 39 OPT_KEYBLOCK, |
39 OPT_SIGNPUBKEY, | 40 OPT_SIGNPUBKEY, |
40 OPT_SIGNPRIVATE, | 41 OPT_SIGNPRIVATE, |
41 OPT_VERSION, | 42 OPT_VERSION, |
42 OPT_VMLINUZ, | 43 OPT_VMLINUZ, |
43 OPT_BOOTLOADER, | 44 OPT_BOOTLOADER, |
44 OPT_CONFIG, | 45 OPT_CONFIG, |
45 OPT_VBLOCKONLY, | 46 OPT_VBLOCKONLY, |
46 OPT_PAD, | 47 OPT_PAD, |
47 OPT_VERBOSE, | 48 OPT_VERBOSE, |
48 }; | 49 }; |
49 | 50 |
50 enum { | 51 enum { |
51 ARCH_ARM, | 52 ARCH_ARM, |
52 ARCH_X86 /* default */ | 53 ARCH_X86 /* default */ |
53 }; | 54 }; |
54 | 55 |
55 static struct option long_opts[] = { | 56 static struct option long_opts[] = { |
56 {"pack", 1, 0, OPT_MODE_PACK }, | 57 {"pack", 1, 0, OPT_MODE_PACK }, |
57 {"repack", 1, 0, OPT_MODE_REPACK }, | 58 {"repack", 1, 0, OPT_MODE_REPACK }, |
58 {"verify", 1, 0, OPT_MODE_VERIFY }, | 59 {"verify", 1, 0, OPT_MODE_VERIFY }, |
59 {"arch", 1, 0, OPT_ARCH }, | 60 {"arch", 1, 0, OPT_ARCH }, |
60 {"oldblob", 1, 0, OPT_OLDBLOB }, | 61 {"oldblob", 1, 0, OPT_OLDBLOB }, |
| 62 {"kloadaddr", 1, 0, OPT_KLOADADDR }, |
61 {"keyblock", 1, 0, OPT_KEYBLOCK }, | 63 {"keyblock", 1, 0, OPT_KEYBLOCK }, |
62 {"signpubkey", 1, 0, OPT_SIGNPUBKEY }, | 64 {"signpubkey", 1, 0, OPT_SIGNPUBKEY }, |
63 {"signprivate", 1, 0, OPT_SIGNPRIVATE }, | 65 {"signprivate", 1, 0, OPT_SIGNPRIVATE }, |
64 {"version", 1, 0, OPT_VERSION }, | 66 {"version", 1, 0, OPT_VERSION }, |
65 {"vmlinuz", 1, 0, OPT_VMLINUZ }, | 67 {"vmlinuz", 1, 0, OPT_VMLINUZ }, |
66 {"bootloader", 1, 0, OPT_BOOTLOADER }, | 68 {"bootloader", 1, 0, OPT_BOOTLOADER }, |
67 {"config", 1, 0, OPT_CONFIG }, | 69 {"config", 1, 0, OPT_CONFIG }, |
68 {"vblockonly", 0, 0, OPT_VBLOCKONLY }, | 70 {"vblockonly", 0, 0, OPT_VBLOCKONLY }, |
69 {"pad", 1, 0, OPT_PAD }, | 71 {"pad", 1, 0, OPT_PAD }, |
70 {"verbose", 0, 0, OPT_VERBOSE }, | 72 {"verbose", 0, 0, OPT_VERBOSE }, |
(...skipping 14 matching lines...) Expand all Loading... |
85 " --keyblock <file> Key block in .keyblock format\n" | 87 " --keyblock <file> Key block in .keyblock format\n" |
86 " --signprivate <file>" | 88 " --signprivate <file>" |
87 " Private key to sign kernel data, in .vbprivk format\n" | 89 " Private key to sign kernel data, in .vbprivk format\n" |
88 " --version <number> Kernel version\n" | 90 " --version <number> Kernel version\n" |
89 " --vmlinuz <file> Linux kernel bzImage file\n" | 91 " --vmlinuz <file> Linux kernel bzImage file\n" |
90 " --bootloader <file> Bootloader stub\n" | 92 " --bootloader <file> Bootloader stub\n" |
91 " --config <file> Command line file\n" | 93 " --config <file> Command line file\n" |
92 " --arch <arch> Cpu architecture (default x86)\n" | 94 " --arch <arch> Cpu architecture (default x86)\n" |
93 "\n" | 95 "\n" |
94 " Optional:\n" | 96 " Optional:\n" |
| 97 " --kloadaddr <address> Assign kernel body load address\n" |
95 " --pad <number> Verification padding size in bytes\n" | 98 " --pad <number> Verification padding size in bytes\n" |
96 " --vblockonly Emit just the verification blob\n", | 99 " --vblockonly Emit just the verification blob\n", |
97 progname); | 100 progname); |
98 fprintf(stderr, | 101 fprintf(stderr, |
99 "\nOR\n\n" | 102 "\nOR\n\n" |
100 "Usage: %s --repack <file> [PARAMETERS]\n" | 103 "Usage: %s --repack <file> [PARAMETERS]\n" |
101 "\n" | 104 "\n" |
102 " Required parameters (of --keyblock, --config, and --version \n" | 105 " Required parameters (of --keyblock, --config, and --version \n" |
103 " at least one is required):\n" | 106 " at least one is required):\n" |
104 " --keyblock <file> Key block in .keyblock format\n" | 107 " --keyblock <file> Key block in .keyblock format\n" |
105 " --signprivate <file>" | 108 " --signprivate <file>" |
106 " Private key to sign kernel data, in .vbprivk format\n" | 109 " Private key to sign kernel data, in .vbprivk format\n" |
107 " --oldblob <file> Previously packed kernel blob\n" | 110 " --oldblob <file> Previously packed kernel blob\n" |
108 " --config <file> New command line file\n" | 111 " --config <file> New command line file\n" |
109 " --version <number> Kernel version\n" | 112 " --version <number> Kernel version\n" |
110 "\n" | 113 "\n" |
111 " Optional:\n" | 114 " Optional:\n" |
| 115 " --kloadaddr <address> Assign kernel body load address\n" |
112 " --pad <number> Verification padding size in bytes\n" | 116 " --pad <number> Verification padding size in bytes\n" |
113 " --vblockonly Emit just the verification blob\n", | 117 " --vblockonly Emit just the verification blob\n", |
114 progname); | 118 progname); |
115 fprintf(stderr, | 119 fprintf(stderr, |
116 "\nOR\n\n" | 120 "\nOR\n\n" |
117 "Usage: %s --verify <file> [PARAMETERS]\n" | 121 "Usage: %s --verify <file> [PARAMETERS]\n" |
118 "\n" | 122 "\n" |
119 " Optional:\n" | 123 " Optional:\n" |
120 " --signpubkey <file>" | 124 " --signpubkey <file>" |
121 " Public key to verify kernel keyblock, in .vbpubk format\n" | 125 " Public key to verify kernel keyblock, in .vbpubk format\n" |
122 " --verbose Print a more detailed report\n" | 126 " --verbose Print a more detailed report\n" |
123 " --keyblock <file>" | 127 " --keyblock <file>" |
124 " Outputs the verified key block, in .keyblock format\n" | 128 " Outputs the verified key block, in .keyblock format\n" |
| 129 " --kloadaddr <address> Assign kernel body load address\n" |
125 "\n", | 130 "\n", |
126 progname); | 131 progname); |
127 return 1; | 132 return 1; |
128 } | 133 } |
129 | 134 |
130 static void Debug(const char *format, ...) { | 135 static void Debug(const char *format, ...) { |
131 if (!opt_debug) | 136 if (!opt_debug) |
132 return; | 137 return; |
133 | 138 |
134 va_list ap; | 139 va_list ap; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 uint8_t *blob; | 197 uint8_t *blob; |
193 | 198 |
194 /* these fields are not always initialized */ | 199 /* these fields are not always initialized */ |
195 VbKernelPreambleHeader* preamble; | 200 VbKernelPreambleHeader* preamble; |
196 VbKeyBlockHeader* key_block; | 201 VbKeyBlockHeader* key_block; |
197 uint8_t *buf; | 202 uint8_t *buf; |
198 | 203 |
199 } blob_t; | 204 } blob_t; |
200 | 205 |
201 /* Given a blob return the location of the kernel command line buffer. */ | 206 /* Given a blob return the location of the kernel command line buffer. */ |
202 static char* BpCmdLineLocation(blob_t *bp) | 207 static char* BpCmdLineLocation(blob_t *bp, uint64_t kernel_body_load_address) |
203 { | 208 { |
204 return (char*)(bp->blob + bp->bootloader_address - CROS_32BIT_ENTRY_ADDR - | 209 return (char*)(bp->blob + bp->bootloader_address - kernel_body_load_address - |
205 CROS_CONFIG_SIZE - CROS_PARAMS_SIZE); | 210 CROS_CONFIG_SIZE - CROS_PARAMS_SIZE); |
206 } | 211 } |
207 | 212 |
208 static void FreeBlob(blob_t *bp) { | 213 static void FreeBlob(blob_t *bp) { |
209 if (bp) { | 214 if (bp) { |
210 if (bp->blob) | 215 if (bp->blob) |
211 Free(bp->blob); | 216 Free(bp->blob); |
212 if (bp->buf) | 217 if (bp->buf) |
213 Free(bp->buf); | 218 Free(bp->buf); |
214 Free(bp); | 219 Free(bp); |
(...skipping 27 matching lines...) Expand all Loading... |
242 } | 247 } |
243 } | 248 } |
244 return config_buf; | 249 return config_buf; |
245 } | 250 } |
246 | 251 |
247 /* Create a blob from its components */ | 252 /* Create a blob from its components */ |
248 static blob_t *NewBlob(uint64_t version, | 253 static blob_t *NewBlob(uint64_t version, |
249 const char* vmlinuz, | 254 const char* vmlinuz, |
250 const char* bootloader_file, | 255 const char* bootloader_file, |
251 const char* config_file, | 256 const char* config_file, |
252 int arch) { | 257 int arch, |
| 258 uint64_t kernel_body_load_address) { |
253 blob_t* bp; | 259 blob_t* bp; |
254 struct linux_kernel_header* lh = 0; | 260 struct linux_kernel_header* lh = 0; |
255 struct linux_kernel_params* params = 0; | 261 struct linux_kernel_params* params = 0; |
256 uint8_t* config_buf; | 262 uint8_t* config_buf; |
257 uint64_t config_size; | 263 uint64_t config_size; |
258 uint8_t* bootloader_buf; | 264 uint8_t* bootloader_buf; |
259 uint64_t bootloader_size; | 265 uint64_t bootloader_size; |
260 uint8_t* kernel_buf; | 266 uint8_t* kernel_buf; |
261 uint64_t kernel_size; | 267 uint64_t kernel_size; |
262 uint64_t kernel32_start = 0; | 268 uint64_t kernel32_start = 0; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 bp->blob = blob; | 339 bp->blob = blob; |
334 | 340 |
335 /* Copy the 32-bit kernel. */ | 341 /* Copy the 32-bit kernel. */ |
336 Debug("kernel goes at blob+=0x%" PRIx64 "\n", now); | 342 Debug("kernel goes at blob+=0x%" PRIx64 "\n", now); |
337 if (kernel32_size) | 343 if (kernel32_size) |
338 Memcpy(blob + now, kernel_buf + kernel32_start, kernel32_size); | 344 Memcpy(blob + now, kernel_buf + kernel32_start, kernel32_size); |
339 now += roundup(now + kernel32_size, CROS_ALIGN); | 345 now += roundup(now + kernel32_size, CROS_ALIGN); |
340 | 346 |
341 Debug("config goes at blob+0x%" PRIx64 "\n", now); | 347 Debug("config goes at blob+0x%" PRIx64 "\n", now); |
342 /* Find the load address of the commandline. We'll need it later. */ | 348 /* Find the load address of the commandline. We'll need it later. */ |
343 cmdline_addr = CROS_32BIT_ENTRY_ADDR + now + | 349 cmdline_addr = kernel_body_load_address + now + |
344 find_cmdline_start((char *)config_buf, config_size); | 350 find_cmdline_start((char *)config_buf, config_size); |
345 Debug(" cmdline_addr=0x%" PRIx64 "\n", cmdline_addr); | 351 Debug(" cmdline_addr=0x%" PRIx64 "\n", cmdline_addr); |
346 | 352 |
347 /* Copy the config. */ | 353 /* Copy the config. */ |
348 if (config_size) | 354 if (config_size) |
349 Memcpy(blob + now, config_buf, config_size); | 355 Memcpy(blob + now, config_buf, config_size); |
350 now += CROS_CONFIG_SIZE; | 356 now += CROS_CONFIG_SIZE; |
351 | 357 |
352 /* The zeropage data is next. Overlay the linux_kernel_header onto it, and | 358 /* The zeropage data is next. Overlay the linux_kernel_header onto it, and |
353 * tweak a few fields. */ | 359 * tweak a few fields. */ |
(...skipping 16 matching lines...) Expand all Loading... |
370 params->e820_entries[0].segment_size = 0x00001000; | 376 params->e820_entries[0].segment_size = 0x00001000; |
371 params->e820_entries[0].segment_type = E820_TYPE_RAM; | 377 params->e820_entries[0].segment_type = E820_TYPE_RAM; |
372 params->e820_entries[1].start_addr = 0xfffff000; | 378 params->e820_entries[1].start_addr = 0xfffff000; |
373 params->e820_entries[1].segment_size = 0x00001000; | 379 params->e820_entries[1].segment_size = 0x00001000; |
374 params->e820_entries[1].segment_type = E820_TYPE_RESERVED; | 380 params->e820_entries[1].segment_type = E820_TYPE_RESERVED; |
375 now += CROS_PARAMS_SIZE; | 381 now += CROS_PARAMS_SIZE; |
376 | 382 |
377 /* Finally, append the bootloader. Remember where it will load in | 383 /* Finally, append the bootloader. Remember where it will load in |
378 * memory, too. */ | 384 * memory, too. */ |
379 Debug("bootloader goes at blob+=0x%" PRIx64 "\n", now); | 385 Debug("bootloader goes at blob+=0x%" PRIx64 "\n", now); |
380 bp->bootloader_address = CROS_32BIT_ENTRY_ADDR + now; | 386 bp->bootloader_address = kernel_body_load_address + now; |
381 bp->bootloader_size = roundup(bootloader_size, CROS_ALIGN); | 387 bp->bootloader_size = roundup(bootloader_size, CROS_ALIGN); |
382 Debug(" bootloader_address=0x%" PRIx64 "\n", bp->bootloader_address); | 388 Debug(" bootloader_address=0x%" PRIx64 "\n", bp->bootloader_address); |
383 Debug(" bootloader_size=0x%" PRIx64 "\n", bp->bootloader_size); | 389 Debug(" bootloader_size=0x%" PRIx64 "\n", bp->bootloader_size); |
384 if (bootloader_size) | 390 if (bootloader_size) |
385 Memcpy(blob + now, bootloader_buf, bootloader_size); | 391 Memcpy(blob + now, bootloader_buf, bootloader_size); |
386 now += bp->bootloader_size; | 392 now += bp->bootloader_size; |
387 Debug("end of blob is 0x%" PRIx64 "\n", now); | 393 Debug("end of blob is 0x%" PRIx64 "\n", now); |
388 | 394 |
389 /* Free input buffers */ | 395 /* Free input buffers */ |
390 Free(kernel_buf); | 396 Free(kernel_buf); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 Free(buf); | 524 Free(buf); |
519 } | 525 } |
520 } | 526 } |
521 return bp; | 527 return bp; |
522 } | 528 } |
523 | 529 |
524 | 530 |
525 /* Pack a .kernel */ | 531 /* Pack a .kernel */ |
526 static int Pack(const char* outfile, const char* keyblock_file, | 532 static int Pack(const char* outfile, const char* keyblock_file, |
527 const char* signprivate, blob_t *bp, uint64_t pad, | 533 const char* signprivate, blob_t *bp, uint64_t pad, |
528 int vblockonly) { | 534 int vblockonly, |
| 535 uint64_t kernel_body_load_address) { |
529 VbPrivateKey* signing_key; | 536 VbPrivateKey* signing_key; |
530 VbSignature* body_sig; | 537 VbSignature* body_sig; |
531 VbKernelPreambleHeader* preamble; | 538 VbKernelPreambleHeader* preamble; |
532 VbKeyBlockHeader* key_block; | 539 VbKeyBlockHeader* key_block; |
533 uint64_t key_block_size; | 540 uint64_t key_block_size; |
534 FILE* f; | 541 FILE* f; |
535 uint64_t i; | 542 uint64_t i; |
536 | 543 |
537 if (!outfile) { | 544 if (!outfile) { |
538 error("Must specify output filename\n"); | 545 error("Must specify output filename\n"); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 | 579 |
573 /* Sign the kernel data */ | 580 /* Sign the kernel data */ |
574 body_sig = CalculateSignature(bp->blob, bp->blob_size, signing_key); | 581 body_sig = CalculateSignature(bp->blob, bp->blob_size, signing_key); |
575 if (!body_sig) { | 582 if (!body_sig) { |
576 error("Error calculating body signature\n"); | 583 error("Error calculating body signature\n"); |
577 return 1; | 584 return 1; |
578 } | 585 } |
579 | 586 |
580 /* Create preamble */ | 587 /* Create preamble */ |
581 preamble = CreateKernelPreamble(bp->kernel_version, | 588 preamble = CreateKernelPreamble(bp->kernel_version, |
582 CROS_32BIT_ENTRY_ADDR, | 589 kernel_body_load_address, |
583 bp->bootloader_address, | 590 bp->bootloader_address, |
584 bp->bootloader_size, | 591 bp->bootloader_size, |
585 body_sig, | 592 body_sig, |
586 pad - key_block_size, | 593 pad - key_block_size, |
587 signing_key); | 594 signing_key); |
588 if (!preamble) { | 595 if (!preamble) { |
589 error("Error creating preamble.\n"); | 596 error("Error creating preamble.\n"); |
590 return 1; | 597 return 1; |
591 } | 598 } |
592 | 599 |
(...skipping 28 matching lines...) Expand all Loading... |
621 | 628 |
622 fclose(f); | 629 fclose(f); |
623 | 630 |
624 /* Success */ | 631 /* Success */ |
625 return 0; | 632 return 0; |
626 } | 633 } |
627 | 634 |
628 /* | 635 /* |
629 * Replace kernel command line in a blob representing a kernel. | 636 * Replace kernel command line in a blob representing a kernel. |
630 */ | 637 */ |
631 static int ReplaceConfig(blob_t* bp, const char* config_file) | 638 static int ReplaceConfig(blob_t* bp, const char* config_file, |
| 639 uint64_t kernel_body_load_address) |
632 { | 640 { |
633 uint8_t* new_conf; | 641 uint8_t* new_conf; |
634 uint64_t config_size; | 642 uint64_t config_size; |
635 | 643 |
636 if (!config_file) { | 644 if (!config_file) { |
637 return 0; | 645 return 0; |
638 } | 646 } |
639 | 647 |
640 new_conf = ReadConfigFile(config_file, &config_size); | 648 new_conf = ReadConfigFile(config_file, &config_size); |
641 if (!new_conf) { | 649 if (!new_conf) { |
642 return 1; | 650 return 1; |
643 } | 651 } |
644 | 652 |
645 /* fill the config buffer with zeros */ | 653 /* fill the config buffer with zeros */ |
646 Memset(BpCmdLineLocation(bp), 0, CROS_CONFIG_SIZE); | 654 Memset(BpCmdLineLocation(bp, kernel_body_load_address), 0, CROS_CONFIG_SIZE); |
647 Memcpy(BpCmdLineLocation(bp), new_conf, config_size); | 655 Memcpy(BpCmdLineLocation(bp, kernel_body_load_address), |
| 656 new_conf, config_size); |
648 Free(new_conf); | 657 Free(new_conf); |
649 return 0; | 658 return 0; |
650 } | 659 } |
651 | 660 |
652 static int Verify(const char* infile, const char* signpubkey, int verbose, | 661 static int Verify(const char* infile, const char* signpubkey, int verbose, |
653 const char* key_block_file) { | 662 const char* key_block_file, |
| 663 uint64_t kernel_body_load_address) { |
654 | 664 |
655 VbKeyBlockHeader* key_block; | 665 VbKeyBlockHeader* key_block; |
656 VbKernelPreambleHeader* preamble; | 666 VbKernelPreambleHeader* preamble; |
657 VbPublicKey* data_key; | 667 VbPublicKey* data_key; |
658 VbPublicKey* sign_key = NULL; | 668 VbPublicKey* sign_key = NULL; |
659 RSAPublicKey* rsa; | 669 RSAPublicKey* rsa; |
660 blob_t* bp; | 670 blob_t* bp; |
661 uint64_t now; | 671 uint64_t now; |
662 int rv = 1; | 672 int rv = 1; |
663 | 673 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 goto verify_exit; | 772 goto verify_exit; |
763 } | 773 } |
764 printf("Body verification succeeded.\n"); | 774 printf("Body verification succeeded.\n"); |
765 | 775 |
766 rv = 0; | 776 rv = 0; |
767 | 777 |
768 if (!verbose) { | 778 if (!verbose) { |
769 goto verify_exit; | 779 goto verify_exit; |
770 } | 780 } |
771 | 781 |
772 printf("Config:\n%s\n", BpCmdLineLocation(bp)); | 782 printf("Config:\n%s\n", BpCmdLineLocation(bp, kernel_body_load_address)); |
773 | 783 |
774 verify_exit: | 784 verify_exit: |
775 FreeBlob(bp); | 785 FreeBlob(bp); |
776 return rv; | 786 return rv; |
777 } | 787 } |
778 | 788 |
779 | 789 |
780 int main(int argc, char* argv[]) { | 790 int main(int argc, char* argv[]) { |
781 char* filename = NULL; | 791 char* filename = NULL; |
782 char* oldfile = NULL; | 792 char* oldfile = NULL; |
783 char* key_block_file = NULL; | 793 char* key_block_file = NULL; |
784 char* signpubkey = NULL; | 794 char* signpubkey = NULL; |
785 char* signprivate = NULL; | 795 char* signprivate = NULL; |
786 int version = -1; | 796 int version = -1; |
787 char* vmlinuz = NULL; | 797 char* vmlinuz = NULL; |
788 char* bootloader = NULL; | 798 char* bootloader = NULL; |
789 char* config_file = NULL; | 799 char* config_file = NULL; |
790 int arch = ARCH_X86; | 800 int arch = ARCH_X86; |
791 int vblockonly = 0; | 801 int vblockonly = 0; |
792 int verbose = 0; | 802 int verbose = 0; |
| 803 uint64_t kernel_body_load_address = CROS_32BIT_ENTRY_ADDR; |
793 uint64_t pad = DEFAULT_PADDING; | 804 uint64_t pad = DEFAULT_PADDING; |
794 int mode = 0; | 805 int mode = 0; |
795 int parse_error = 0; | 806 int parse_error = 0; |
796 char* e; | 807 char* e; |
797 int i,r; | 808 int i,r; |
798 blob_t *bp; | 809 blob_t *bp; |
799 | 810 |
800 | 811 |
801 char *progname = strrchr(argv[0], '/'); | 812 char *progname = strrchr(argv[0], '/'); |
802 if (progname) | 813 if (progname) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
837 else { | 848 else { |
838 fprintf(stderr, "Unknown architecture string: %s\n", optarg); | 849 fprintf(stderr, "Unknown architecture string: %s\n", optarg); |
839 parse_error = 1; | 850 parse_error = 1; |
840 } | 851 } |
841 break; | 852 break; |
842 | 853 |
843 case OPT_OLDBLOB: | 854 case OPT_OLDBLOB: |
844 oldfile = optarg; | 855 oldfile = optarg; |
845 break; | 856 break; |
846 | 857 |
| 858 case OPT_KLOADADDR: |
| 859 kernel_body_load_address = strtoul(optarg, &e, 0); |
| 860 if (!*optarg || (e && *e)) { |
| 861 fprintf(stderr, "Invalid --kloadaddr\n"); |
| 862 parse_error = 1; |
| 863 } |
| 864 break; |
| 865 |
847 case OPT_KEYBLOCK: | 866 case OPT_KEYBLOCK: |
848 key_block_file = optarg; | 867 key_block_file = optarg; |
849 break; | 868 break; |
850 | 869 |
851 case OPT_SIGNPUBKEY: | 870 case OPT_SIGNPUBKEY: |
852 signpubkey = optarg; | 871 signpubkey = optarg; |
853 break; | 872 break; |
854 | 873 |
855 case OPT_SIGNPRIVATE: | 874 case OPT_SIGNPRIVATE: |
856 signprivate = optarg; | 875 signprivate = optarg; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 verbose = 1; | 911 verbose = 1; |
893 break; | 912 break; |
894 } | 913 } |
895 } | 914 } |
896 | 915 |
897 if (parse_error) | 916 if (parse_error) |
898 return PrintHelp(progname); | 917 return PrintHelp(progname); |
899 | 918 |
900 switch(mode) { | 919 switch(mode) { |
901 case OPT_MODE_PACK: | 920 case OPT_MODE_PACK: |
902 bp = NewBlob(version, vmlinuz, bootloader, config_file, arch); | 921 bp = NewBlob(version, vmlinuz, bootloader, config_file, arch, |
| 922 kernel_body_load_address); |
903 if (!bp) | 923 if (!bp) |
904 return 1; | 924 return 1; |
905 r = Pack(filename, key_block_file, signprivate, bp, pad, vblockonly); | 925 r = Pack(filename, key_block_file, signprivate, bp, pad, vblockonly, |
| 926 kernel_body_load_address); |
906 FreeBlob(bp); | 927 FreeBlob(bp); |
907 return r; | 928 return r; |
908 | 929 |
909 case OPT_MODE_REPACK: | 930 case OPT_MODE_REPACK: |
910 if (!config_file && !key_block_file && (version<0)) { | 931 if (!config_file && !key_block_file && (version<0)) { |
911 fprintf(stderr, | 932 fprintf(stderr, |
912 "You must supply at least one of " | 933 "You must supply at least one of " |
913 "--config, --keyblock or --version\n"); | 934 "--config, --keyblock or --version\n"); |
914 return 1; | 935 return 1; |
915 } | 936 } |
916 | 937 |
917 bp = OldBlob(oldfile); | 938 bp = OldBlob(oldfile); |
918 if (!bp) | 939 if (!bp) |
919 return 1; | 940 return 1; |
920 r = ReplaceConfig(bp, config_file); | 941 r = ReplaceConfig(bp, config_file, kernel_body_load_address); |
921 if (!r) { | 942 if (!r) { |
922 if (version >= 0) { | 943 if (version >= 0) { |
923 bp->kernel_version = (uint64_t) version; | 944 bp->kernel_version = (uint64_t) version; |
924 } | 945 } |
925 r = Pack(filename, key_block_file, signprivate, bp, pad, vblockonly); | 946 r = Pack(filename, key_block_file, signprivate, bp, pad, vblockonly, |
| 947 kernel_body_load_address); |
926 } | 948 } |
927 FreeBlob(bp); | 949 FreeBlob(bp); |
928 return r; | 950 return r; |
929 | 951 |
930 case OPT_MODE_VERIFY: | 952 case OPT_MODE_VERIFY: |
931 return Verify(filename, signpubkey, verbose, key_block_file); | 953 return Verify(filename, signpubkey, verbose, key_block_file, |
| 954 kernel_body_load_address); |
932 | 955 |
933 default: | 956 default: |
934 fprintf(stderr, | 957 fprintf(stderr, |
935 "You must specify a mode: --pack, --repack or --verify\n"); | 958 "You must specify a mode: --pack, --repack or --verify\n"); |
936 return PrintHelp(progname); | 959 return PrintHelp(progname); |
937 } | 960 } |
938 } | 961 } |
OLD | NEW |