diff options
Diffstat (limited to 'utility/dump_kernel_config_lib.c')
-rw-r--r-- | utility/dump_kernel_config_lib.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/utility/dump_kernel_config_lib.c b/utility/dump_kernel_config_lib.c new file mode 100644 index 00000000..a6989e1c --- /dev/null +++ b/utility/dump_kernel_config_lib.c @@ -0,0 +1,88 @@ +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Exports the kernel commandline from a given partition/image. + */ + +#include <stdio.h> +#include <sys/mman.h> + +#include "dump_kernel_config.h" +#include "host_common.h" +#include "kernel_blob.h" +#include "vboot_api.h" + +uint8_t* find_kernel_config(uint8_t* blob, uint64_t blob_size, + uint64_t kernel_body_load_address) { + + VbKeyBlockHeader* key_block; + VbKernelPreambleHeader* preamble; + uint32_t now = 0; + uint32_t offset = 0; + + /* Skip the key block */ + key_block = (VbKeyBlockHeader*)blob; + now += key_block->key_block_size; + if (now + blob > blob + blob_size) { + VbExError("key_block_size advances past the end of the blob\n"); + return NULL; + } + + /* Open up the preamble */ + preamble = (VbKernelPreambleHeader*)(blob + now); + now += preamble->preamble_size; + if (now + blob > blob + blob_size) { + VbExError("preamble_size advances past the end of the blob\n"); + return NULL; + } + + /* Read body_load_address from preamble if no kernel_body_load_address */ + if (kernel_body_load_address == CROS_NO_ENTRY_ADDR) + kernel_body_load_address = preamble->body_load_address; + + /* The x86 kernels have a pointer to the kernel commandline in the zeropage + * table, but that's irrelevant for ARM. Both types keep the config blob in + * the same place, so just go find it. */ + offset = preamble->bootloader_address - + (kernel_body_load_address + CROS_PARAMS_SIZE + + CROS_CONFIG_SIZE) + now; + if (offset > blob_size) { + VbExError("params are outside of the memory blob: %x\n", offset); + return NULL; + } + return blob + offset; +} + +void* MapFile(const char* filename, size_t *size) { + FILE* f; + uint8_t* buf; + long file_size = 0; + + f = fopen(filename, "rb"); + if (!f) { + VBDEBUG(("Unable to open file %s\n", filename)); + return NULL; + } + + fseek(f, 0, SEEK_END); + file_size = ftell(f); + rewind(f); + + if (file_size <= 0) { + fclose(f); + return NULL; + } + *size = (size_t) file_size; + + /* Uses a host primitive as this is not meant for firmware use. */ + buf = mmap(NULL, *size, PROT_READ, MAP_PRIVATE, fileno(f), 0); + if (buf == MAP_FAILED) { + VbExError("Failed to mmap the file %s\n", filename); + fclose(f); + return NULL; + } + + fclose(f); + return buf; +} |