Index: utility/dump_kernel_config.c |
diff --git a/utility/dump_kernel_config.c b/utility/dump_kernel_config.c |
index 4decc7de41a712f346e12417d70381c7d61c079a..b44a12e06a1731f2b8c70e81fe078466aaa54470 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 <getopt.h> |
#include <inttypes.h> /* For uint64_t */ |
#include <stdio.h> |
#include <stdlib.h> |
@@ -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 <image/blockdevice>\n" |
+ "Usage: dump_kernel_config [--kloadaddr <ADDRESS>] " |
+ "<image/blockdevice>\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); |