| Index: utility/vbutil_kernel.c
|
| diff --git a/utility/vbutil_kernel.c b/utility/vbutil_kernel.c
|
| index c2b32d877bcd5c2938384c03c27087aca34111d9..e6ad031fb311bd25a1dda47ac55ecdc4b00c68e6 100644
|
| --- a/utility/vbutil_kernel.c
|
| +++ b/utility/vbutil_kernel.c
|
| @@ -33,6 +33,7 @@ enum {
|
| OPT_MODE_PACK = 1000,
|
| OPT_MODE_REPACK,
|
| OPT_MODE_VERIFY,
|
| + OPT_ARCH,
|
| OPT_OLDBLOB,
|
| OPT_KEYBLOCK,
|
| OPT_SIGNPUBKEY,
|
| @@ -46,10 +47,17 @@ enum {
|
| OPT_VERBOSE,
|
| };
|
|
|
| +enum {
|
| + ARCH_NO_SUCH_ARCHITECTURE = -1,
|
| + ARCH_ARM,
|
| + ARCH_X86
|
| +};
|
| +
|
| static struct option long_opts[] = {
|
| {"pack", 1, 0, OPT_MODE_PACK },
|
| {"repack", 1, 0, OPT_MODE_REPACK },
|
| {"verify", 1, 0, OPT_MODE_VERIFY },
|
| + {"arch", 1, 0, OPT_ARCH },
|
| {"oldblob", 1, 0, OPT_OLDBLOB },
|
| {"keyblock", 1, 0, OPT_KEYBLOCK },
|
| {"signpubkey", 1, 0, OPT_SIGNPUBKEY },
|
| @@ -82,6 +90,7 @@ static int PrintHelp(char *progname) {
|
| " --vmlinuz <file> Linux kernel bzImage file\n"
|
| " --bootloader <file> Bootloader stub\n"
|
| " --config <file> Command line file\n"
|
| + " --arch <arch> Cpu architecture\n"
|
| "\n"
|
| " Optional:\n"
|
| " --pad <number> Verification padding size in bytes\n"
|
| @@ -240,10 +249,11 @@ static uint8_t* ReadConfigFile(const char* config_file, uint64_t* config_size)
|
| static blob_t *NewBlob(uint64_t version,
|
| const char* vmlinuz,
|
| const char* bootloader_file,
|
| - const char* config_file) {
|
| - blob_t *bp;
|
| - struct linux_kernel_header *lh = 0;
|
| - struct linux_kernel_params *params = 0;
|
| + const char* config_file,
|
| + int arch) {
|
| + blob_t* bp;
|
| + struct linux_kernel_header* lh = 0;
|
| + struct linux_kernel_params* params = 0;
|
| uint8_t* config_buf;
|
| uint64_t config_size;
|
| uint8_t* bootloader_buf;
|
| @@ -294,14 +304,17 @@ static blob_t *NewBlob(uint64_t version,
|
| return 0;
|
| }
|
|
|
| - /* The first part of vmlinuz is a header, followed by a real-mode
|
| - * boot stub. We only want the 32-bit part. */
|
| - lh = (struct linux_kernel_header *)kernel_buf;
|
| - kernel32_start = (lh->setup_sects + 1) << 9;
|
| - if (kernel32_start >= kernel_size) {
|
| - error("Malformed kernel\n");
|
| - return 0;
|
| - }
|
| + if (arch == ARCH_X86) {
|
| + /* The first part of vmlinuz is a header, followed by a real-mode
|
| + * boot stub. We only want the 32-bit part. */
|
| + lh = (struct linux_kernel_header *)kernel_buf;
|
| + kernel32_start = (lh->setup_sects + 1) << 9;
|
| + if (kernel32_start >= kernel_size) {
|
| + error("Malformed kernel\n");
|
| + return 0;
|
| + }
|
| + } else
|
| + kernel32_start = 0;
|
| kernel32_size = kernel_size - kernel32_start;
|
| Debug(" kernel32_start=0x%" PRIx64 "\n", kernel32_start);
|
| Debug(" kernel32_size=0x%" PRIx64 "\n", kernel32_size);
|
| @@ -341,8 +354,12 @@ static blob_t *NewBlob(uint64_t version,
|
| * tweak a few fields. */
|
| Debug("params goes at blob+=0x%" PRIx64 "\n", now);
|
| params = (struct linux_kernel_params *)(blob + now);
|
| - Memcpy(&(params->setup_sects), &(lh->setup_sects),
|
| - sizeof(*lh) - offsetof(struct linux_kernel_header, setup_sects));
|
| + if (arch == ARCH_X86)
|
| + Memcpy(&(params->setup_sects), &(lh->setup_sects),
|
| + sizeof(*lh) - offsetof(struct linux_kernel_header, setup_sects));
|
| + else
|
| + Memset(&(params->setup_sects), 0,
|
| + sizeof(*lh) - offsetof(struct linux_kernel_header, setup_sects));
|
| params->boot_flag = 0;
|
| params->ramdisk_image = 0; /* we don't support initrd */
|
| params->ramdisk_size = 0;
|
| @@ -771,6 +788,7 @@ int main(int argc, char* argv[]) {
|
| char* vmlinuz = NULL;
|
| char* bootloader = NULL;
|
| char* config_file = NULL;
|
| + int arch = ARCH_NO_SUCH_ARCHITECTURE;
|
| int vblockonly = 0;
|
| int verbose = 0;
|
| uint64_t pad = DEFAULT_PADDING;
|
| @@ -812,6 +830,17 @@ int main(int argc, char* argv[]) {
|
| filename = optarg;
|
| break;
|
|
|
| + case OPT_ARCH:
|
| + if (!strcasecmp(optarg, "x86"))
|
| + arch = ARCH_X86;
|
| + else if (!strcasecmp(optarg, "arm"))
|
| + arch = ARCH_ARM;
|
| + else {
|
| + fprintf(stderr, "Unknown architecture string: %s\n", optarg);
|
| + parse_error = 1;
|
| + }
|
| + break;
|
| +
|
| case OPT_OLDBLOB:
|
| oldfile = optarg;
|
| break;
|
| @@ -871,7 +900,11 @@ int main(int argc, char* argv[]) {
|
|
|
| switch(mode) {
|
| case OPT_MODE_PACK:
|
| - bp = NewBlob(version, vmlinuz, bootloader, config_file);
|
| + if (arch == ARCH_NO_SUCH_ARCHITECTURE) {
|
| + fprintf(stderr, "You must specify --arch\n");
|
| + return 1;
|
| + }
|
| + bp = NewBlob(version, vmlinuz, bootloader, config_file, arch);
|
| if (!bp)
|
| return 1;
|
| r = Pack(filename, key_block_file, signprivate, bp, pad, vblockonly);
|
| @@ -892,7 +925,7 @@ int main(int argc, char* argv[]) {
|
| r = ReplaceConfig(bp, config_file);
|
| if (!r) {
|
| if (version >= 0) {
|
| - bp->kernel_version = (uint64_t) version;
|
| + bp->kernel_version = (uint64_t) version;
|
| }
|
| r = Pack(filename, key_block_file, signprivate, bp, pad, vblockonly);
|
| }
|
|
|