From 2c0711bf540cbbf71c7fe620f1c8290c67fd5acc Mon Sep 17 00:00:00 2001 From: Che-Liang Chiou Date: Tue, 22 Mar 2011 13:15:19 +0800 Subject: Revert "Revert "Add --kloadaddr option to utilities"" This reverts commit bc7a84d9a1bef3fb8c1e2709033f6c9777599fe9. It was a false alarm that --kloadaddr causes chromeos-install on a x86 targets to fail. The error of chromeos-install cannot be reproduced, and judging by the reported error message, the error should not be attributed to --kloadaddr, which has no effect in x86 targets. So --kloadaddr is restored. Verification process are below: (Verify that --kloadaddr option is restored) $ dump_kernel_config -h Expected argument after options dump_kernel_config - Prints the kernel command line Usage: dump_kernel_config [--kloadaddr
] (Setup a x86 target with kernel-next profile) $ rm -rf /build/${X86_TARGET} $ ./setup_board --board=${X86_TARGET} --profile=kernel-next $ ./build_packages --board=${X86_TARGET} $ ./build_image --board=${X86_TARGET} (Run chromeos-install on target machine successfully) $ /usr/sbin/chromeos-install (Change directory to where image sits) $ cd ~/trunk/src/build/images/${X86_TARGET}/latest (Unpack Chromium OS image) $ ./unpack_partitions.sh chromiumos_image.bin (Verify that dump_kernel_config runs successfully) $ dump_kernel_config part_2 console=tty2 init=/sbin/init add_efi_memmap boot=local noresume noswap i915.modeset=1 cros_secure kern_guid=%U tpm_tis.force=1 tpm_tis.interrupts=0 nmi_watchdog=panic,lapic i8042.nomux=1 root=/dev/dm-0 quiet loglevel=1 rootwait ro dm_verity.error_behavior=3 dm_verity.max_bios=-1 dm_verity.dev_wait=1 dm="vroot none ro,0 1740800 verity %U+1 %U+1 1740800 1 sha1 c357e07395150770ce25ebc0e3c6d15941675c58" (Run load_kernel_test) $ load_kernel_test -b 2 chromiumos_image.bin /usr/share/vboot/devkeys/recovery_key.vbpubk Read 2088 bytes of key from /usr/share/vboot/devkeys/recovery_key.vbpubk bootflags = 6 Reading from image: chromiumos_image.bin Ending LBA: 3989538 Read(1, 1) Read(2, 32) Read(3989506, 32) Read(3989538, 1) Read(4096, 128) Read(4224, 6472) LoadKernel() returned 0 Partition number: 2 Bootloader address: 4345856 Bootloader size: 16384 Partition guid: b2a453b0-a64a-5c4d-a957-1388cea384a5 R=marcheu@chromium.org,sjg@chromium.org BUG=none TEST=see verification process above Review URL: http://codereview.chromium.org/6685079 Change-Id: I932753197550b853495f2c03e8880ad71df765a7 --- utility/dump_kernel_config.c | 60 ++++++++++++++++++++++++++++++++++++++------ utility/vbutil_kernel.c | 59 ++++++++++++++++++++++++++++++------------- 2 files changed, 94 insertions(+), 25 deletions(-) diff --git a/utility/dump_kernel_config.c b/utility/dump_kernel_config.c index 4decc7de..b44a12e0 100644 --- a/utility/dump_kernel_config.c +++ b/utility/dump_kernel_config.c @@ -5,6 +5,7 @@ * Exports the kernel commandline from a given partition/image. */ +#include #include /* For uint64_t */ #include #include @@ -16,17 +17,28 @@ #include "vboot_common.h" #include "vboot_struct.h" +enum { + OPT_KLOADADDR = 1000, +}; + +static struct option long_opts[] = { + { "kloadaddr", 1, 0, OPT_KLOADADDR }, + { NULL, 0, 0, 0 } +}; + /* Print help and return error */ static int PrintHelp(void) { puts("dump_kernel_config - Prints the kernel command line\n" "\n" - "Usage: dump_kernel_config \n" + "Usage: dump_kernel_config [--kloadaddr
] " + "\n" "\n" ""); return 1; } -static uint8_t* find_kernel_config(uint8_t* blob, uint64_t blob_size) { +static uint8_t* find_kernel_config(uint8_t* blob, uint64_t blob_size, + uint64_t kernel_body_load_address) { VbKeyBlockHeader* key_block; VbKernelPreambleHeader* preamble; struct linux_kernel_params *params; @@ -52,7 +64,7 @@ static uint8_t* find_kernel_config(uint8_t* blob, uint64_t blob_size) { /* The parameters are packed before the bootloader and there is no specific * pointer to it so we just walk back by its allocated size. */ offset = preamble->bootloader_address - - (CROS_32BIT_ENTRY_ADDR + CROS_PARAMS_SIZE) + now; + (kernel_body_load_address + CROS_PARAMS_SIZE) + now; if (offset > blob_size) { error("params are outside of the memory blob: %x\n", offset); return NULL; @@ -60,7 +72,7 @@ static uint8_t* find_kernel_config(uint8_t* blob, uint64_t blob_size) { params = (struct linux_kernel_params *)(blob + offset); /* Grab the offset to the kernel command line using the supplied pointer. */ - offset = params->cmd_line_ptr - CROS_32BIT_ENTRY_ADDR + now; + offset = params->cmd_line_ptr - kernel_body_load_address + now; if (offset > blob_size) { error("cmdline is outside of the memory blob: %x\n", offset); return NULL; @@ -104,10 +116,43 @@ static void* MapFile(const char *filename, size_t *size) { int main(int argc, char* argv[]) { uint8_t* blob; size_t blob_size; - char* infile = argv[1]; + char* infile = NULL; uint8_t *config = NULL; + uint64_t kernel_body_load_address = CROS_32BIT_ENTRY_ADDR; + int parse_error = 0; + char *e; + int i; + + while (((i = getopt_long(argc, argv, ":", long_opts, NULL)) != -1) && + !parse_error) { + switch (i) { + default: + case '?': + /* Unhandled option */ + parse_error = 1; + break; + + case 0: + /* silently handled option */ + break; + + case OPT_KLOADADDR: + kernel_body_load_address = strtoul(optarg, &e, 0); + if (!*optarg || (e && *e)) { + fprintf(stderr, "Invalid --kloadaddr\n"); + parse_error = 1; + } + break; + } + } + + if (optind >= argc) { + fprintf(stderr, "Expected argument after options\n"); + parse_error = 1; + } else + infile = argv[optind]; - if (argc < 2) + if (parse_error) return PrintHelp(); if (!infile || !*infile) { @@ -122,7 +167,8 @@ int main(int argc, char* argv[]) { return 1; } - config = find_kernel_config(blob, (uint64_t)blob_size); + config = find_kernel_config(blob, (uint64_t)blob_size, + kernel_body_load_address); if (!config) { error("Error parsing input file\n"); munmap(blob, blob_size); diff --git a/utility/vbutil_kernel.c b/utility/vbutil_kernel.c index a8986db5..85f8a514 100644 --- a/utility/vbutil_kernel.c +++ b/utility/vbutil_kernel.c @@ -35,6 +35,7 @@ enum { OPT_MODE_VERIFY, OPT_ARCH, OPT_OLDBLOB, + OPT_KLOADADDR, OPT_KEYBLOCK, OPT_SIGNPUBKEY, OPT_SIGNPRIVATE, @@ -58,6 +59,7 @@ static struct option long_opts[] = { {"verify", 1, 0, OPT_MODE_VERIFY }, {"arch", 1, 0, OPT_ARCH }, {"oldblob", 1, 0, OPT_OLDBLOB }, + {"kloadaddr", 1, 0, OPT_KLOADADDR }, {"keyblock", 1, 0, OPT_KEYBLOCK }, {"signpubkey", 1, 0, OPT_SIGNPUBKEY }, {"signprivate", 1, 0, OPT_SIGNPRIVATE }, @@ -92,6 +94,7 @@ static int PrintHelp(char *progname) { " --arch Cpu architecture (default x86)\n" "\n" " Optional:\n" + " --kloadaddr
Assign kernel body load address\n" " --pad Verification padding size in bytes\n" " --vblockonly Emit just the verification blob\n", progname); @@ -109,6 +112,7 @@ static int PrintHelp(char *progname) { " --version Kernel version\n" "\n" " Optional:\n" + " --kloadaddr
Assign kernel body load address\n" " --pad Verification padding size in bytes\n" " --vblockonly Emit just the verification blob\n", progname); @@ -121,7 +125,8 @@ static int PrintHelp(char *progname) { " Public key to verify kernel keyblock, in .vbpubk format\n" " --verbose Print a more detailed report\n" " --keyblock " - " Outputs the verified key block, in .keyblock format\n" + " Outputs the verified key block, in .keyblock format\n" + " --kloadaddr
Assign kernel body load address\n" "\n", progname); return 1; @@ -199,9 +204,9 @@ typedef struct blob_s { } blob_t; /* Given a blob return the location of the kernel command line buffer. */ -static char* BpCmdLineLocation(blob_t *bp) +static char* BpCmdLineLocation(blob_t *bp, uint64_t kernel_body_load_address) { - return (char*)(bp->blob + bp->bootloader_address - CROS_32BIT_ENTRY_ADDR - + return (char*)(bp->blob + bp->bootloader_address - kernel_body_load_address - CROS_CONFIG_SIZE - CROS_PARAMS_SIZE); } @@ -249,7 +254,8 @@ static blob_t *NewBlob(uint64_t version, const char* vmlinuz, const char* bootloader_file, const char* config_file, - int arch) { + int arch, + uint64_t kernel_body_load_address) { blob_t* bp; struct linux_kernel_header* lh = 0; struct linux_kernel_params* params = 0; @@ -340,7 +346,7 @@ static blob_t *NewBlob(uint64_t version, Debug("config goes at blob+0x%" PRIx64 "\n", now); /* Find the load address of the commandline. We'll need it later. */ - cmdline_addr = CROS_32BIT_ENTRY_ADDR + now + + cmdline_addr = kernel_body_load_address + now + find_cmdline_start((char *)config_buf, config_size); Debug(" cmdline_addr=0x%" PRIx64 "\n", cmdline_addr); @@ -377,7 +383,7 @@ static blob_t *NewBlob(uint64_t version, /* Finally, append the bootloader. Remember where it will load in * memory, too. */ Debug("bootloader goes at blob+=0x%" PRIx64 "\n", now); - bp->bootloader_address = CROS_32BIT_ENTRY_ADDR + now; + bp->bootloader_address = kernel_body_load_address + now; bp->bootloader_size = roundup(bootloader_size, CROS_ALIGN); Debug(" bootloader_address=0x%" PRIx64 "\n", bp->bootloader_address); Debug(" bootloader_size=0x%" PRIx64 "\n", bp->bootloader_size); @@ -525,7 +531,8 @@ unwind_oldblob: /* Pack a .kernel */ static int Pack(const char* outfile, const char* keyblock_file, const char* signprivate, blob_t *bp, uint64_t pad, - int vblockonly) { + int vblockonly, + uint64_t kernel_body_load_address) { VbPrivateKey* signing_key; VbSignature* body_sig; VbKernelPreambleHeader* preamble; @@ -579,7 +586,7 @@ static int Pack(const char* outfile, const char* keyblock_file, /* Create preamble */ preamble = CreateKernelPreamble(bp->kernel_version, - CROS_32BIT_ENTRY_ADDR, + kernel_body_load_address, bp->bootloader_address, bp->bootloader_size, body_sig, @@ -628,7 +635,8 @@ static int Pack(const char* outfile, const char* keyblock_file, /* * Replace kernel command line in a blob representing a kernel. */ -static int ReplaceConfig(blob_t* bp, const char* config_file) +static int ReplaceConfig(blob_t* bp, const char* config_file, + uint64_t kernel_body_load_address) { uint8_t* new_conf; uint64_t config_size; @@ -643,14 +651,16 @@ static int ReplaceConfig(blob_t* bp, const char* config_file) } /* fill the config buffer with zeros */ - Memset(BpCmdLineLocation(bp), 0, CROS_CONFIG_SIZE); - Memcpy(BpCmdLineLocation(bp), new_conf, config_size); + Memset(BpCmdLineLocation(bp, kernel_body_load_address), 0, CROS_CONFIG_SIZE); + Memcpy(BpCmdLineLocation(bp, kernel_body_load_address), + new_conf, config_size); Free(new_conf); return 0; } static int Verify(const char* infile, const char* signpubkey, int verbose, - const char* key_block_file) { + const char* key_block_file, + uint64_t kernel_body_load_address) { VbKeyBlockHeader* key_block; VbKernelPreambleHeader* preamble; @@ -769,7 +779,7 @@ static int Verify(const char* infile, const char* signpubkey, int verbose, goto verify_exit; } - printf("Config:\n%s\n", BpCmdLineLocation(bp)); + printf("Config:\n%s\n", BpCmdLineLocation(bp, kernel_body_load_address)); verify_exit: FreeBlob(bp); @@ -790,6 +800,7 @@ int main(int argc, char* argv[]) { int arch = ARCH_X86; int vblockonly = 0; int verbose = 0; + uint64_t kernel_body_load_address = CROS_32BIT_ENTRY_ADDR; uint64_t pad = DEFAULT_PADDING; int mode = 0; int parse_error = 0; @@ -844,6 +855,14 @@ int main(int argc, char* argv[]) { oldfile = optarg; break; + case OPT_KLOADADDR: + kernel_body_load_address = strtoul(optarg, &e, 0); + if (!*optarg || (e && *e)) { + fprintf(stderr, "Invalid --kloadaddr\n"); + parse_error = 1; + } + break; + case OPT_KEYBLOCK: key_block_file = optarg; break; @@ -899,10 +918,12 @@ int main(int argc, char* argv[]) { switch(mode) { case OPT_MODE_PACK: - bp = NewBlob(version, vmlinuz, bootloader, config_file, arch); + bp = NewBlob(version, vmlinuz, bootloader, config_file, arch, + kernel_body_load_address); if (!bp) return 1; - r = Pack(filename, key_block_file, signprivate, bp, pad, vblockonly); + r = Pack(filename, key_block_file, signprivate, bp, pad, vblockonly, + kernel_body_load_address); FreeBlob(bp); return r; @@ -917,18 +938,20 @@ int main(int argc, char* argv[]) { bp = OldBlob(oldfile); if (!bp) return 1; - r = ReplaceConfig(bp, config_file); + r = ReplaceConfig(bp, config_file, kernel_body_load_address); if (!r) { if (version >= 0) { bp->kernel_version = (uint64_t) version; } - r = Pack(filename, key_block_file, signprivate, bp, pad, vblockonly); + r = Pack(filename, key_block_file, signprivate, bp, pad, vblockonly, + kernel_body_load_address); } FreeBlob(bp); return r; case OPT_MODE_VERIFY: - return Verify(filename, signpubkey, verbose, key_block_file); + return Verify(filename, signpubkey, verbose, key_block_file, + kernel_body_load_address); default: fprintf(stderr, -- cgit v1.2.1