Add --arch flag to pack mode of vbutil_kernel

When --arch flag is not x86, x86-only operations in pack mode are
turned off so that we can reuse vbutil_kernel to generate kernel partition
images for other targets, such as arm.

See CL:6538014 for its application.

BUG=chromium-os:3790
TEST=Run "emerge vboot_reference" successfully

Review URL: http://codereview.chromium.org/6538015

Change-Id: If45cf092d1ecc762fad6fda1aa57d23e26a7e47a
This commit is contained in:
Che-Liang Chiou
2011-02-22 11:16:51 +08:00
parent f6af9dde86
commit 0376203b41

View File

@@ -33,6 +33,7 @@ enum {
OPT_MODE_PACK = 1000, OPT_MODE_PACK = 1000,
OPT_MODE_REPACK, OPT_MODE_REPACK,
OPT_MODE_VERIFY, OPT_MODE_VERIFY,
OPT_ARCH,
OPT_OLDBLOB, OPT_OLDBLOB,
OPT_KEYBLOCK, OPT_KEYBLOCK,
OPT_SIGNPUBKEY, OPT_SIGNPUBKEY,
@@ -46,10 +47,16 @@ enum {
OPT_VERBOSE, OPT_VERBOSE,
}; };
enum {
ARCH_ARM,
ARCH_X86 /* default */
};
static struct option long_opts[] = { static struct option long_opts[] = {
{"pack", 1, 0, OPT_MODE_PACK }, {"pack", 1, 0, OPT_MODE_PACK },
{"repack", 1, 0, OPT_MODE_REPACK }, {"repack", 1, 0, OPT_MODE_REPACK },
{"verify", 1, 0, OPT_MODE_VERIFY }, {"verify", 1, 0, OPT_MODE_VERIFY },
{"arch", 1, 0, OPT_ARCH },
{"oldblob", 1, 0, OPT_OLDBLOB }, {"oldblob", 1, 0, OPT_OLDBLOB },
{"keyblock", 1, 0, OPT_KEYBLOCK }, {"keyblock", 1, 0, OPT_KEYBLOCK },
{"signpubkey", 1, 0, OPT_SIGNPUBKEY }, {"signpubkey", 1, 0, OPT_SIGNPUBKEY },
@@ -82,6 +89,7 @@ static int PrintHelp(char *progname) {
" --vmlinuz <file> Linux kernel bzImage file\n" " --vmlinuz <file> Linux kernel bzImage file\n"
" --bootloader <file> Bootloader stub\n" " --bootloader <file> Bootloader stub\n"
" --config <file> Command line file\n" " --config <file> Command line file\n"
" --arch <arch> Cpu architecture (default x86)\n"
"\n" "\n"
" Optional:\n" " Optional:\n"
" --pad <number> Verification padding size in bytes\n" " --pad <number> Verification padding size in bytes\n"
@@ -240,10 +248,11 @@ static uint8_t* ReadConfigFile(const char* config_file, uint64_t* config_size)
static blob_t *NewBlob(uint64_t version, static blob_t *NewBlob(uint64_t version,
const char* vmlinuz, const char* vmlinuz,
const char* bootloader_file, const char* bootloader_file,
const char* config_file) { const char* config_file,
blob_t *bp; int arch) {
struct linux_kernel_header *lh = 0; blob_t* bp;
struct linux_kernel_params *params = 0; struct linux_kernel_header* lh = 0;
struct linux_kernel_params* params = 0;
uint8_t* config_buf; uint8_t* config_buf;
uint64_t config_size; uint64_t config_size;
uint8_t* bootloader_buf; uint8_t* bootloader_buf;
@@ -294,14 +303,17 @@ static blob_t *NewBlob(uint64_t version,
return 0; return 0;
} }
/* The first part of vmlinuz is a header, followed by a real-mode if (arch == ARCH_X86) {
* boot stub. We only want the 32-bit part. */ /* The first part of vmlinuz is a header, followed by a real-mode
lh = (struct linux_kernel_header *)kernel_buf; * boot stub. We only want the 32-bit part. */
kernel32_start = (lh->setup_sects + 1) << 9; lh = (struct linux_kernel_header *)kernel_buf;
if (kernel32_start >= kernel_size) { kernel32_start = (lh->setup_sects + 1) << 9;
error("Malformed kernel\n"); if (kernel32_start >= kernel_size) {
return 0; error("Malformed kernel\n");
} return 0;
}
} else
kernel32_start = 0;
kernel32_size = kernel_size - kernel32_start; kernel32_size = kernel_size - kernel32_start;
Debug(" kernel32_start=0x%" PRIx64 "\n", kernel32_start); Debug(" kernel32_start=0x%" PRIx64 "\n", kernel32_start);
Debug(" kernel32_size=0x%" PRIx64 "\n", kernel32_size); Debug(" kernel32_size=0x%" PRIx64 "\n", kernel32_size);
@@ -341,8 +353,12 @@ static blob_t *NewBlob(uint64_t version,
* tweak a few fields. */ * tweak a few fields. */
Debug("params goes at blob+=0x%" PRIx64 "\n", now); Debug("params goes at blob+=0x%" PRIx64 "\n", now);
params = (struct linux_kernel_params *)(blob + now); params = (struct linux_kernel_params *)(blob + now);
Memcpy(&(params->setup_sects), &(lh->setup_sects), if (arch == ARCH_X86)
sizeof(*lh) - offsetof(struct linux_kernel_header, setup_sects)); 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->boot_flag = 0;
params->ramdisk_image = 0; /* we don't support initrd */ params->ramdisk_image = 0; /* we don't support initrd */
params->ramdisk_size = 0; params->ramdisk_size = 0;
@@ -771,6 +787,7 @@ int main(int argc, char* argv[]) {
char* vmlinuz = NULL; char* vmlinuz = NULL;
char* bootloader = NULL; char* bootloader = NULL;
char* config_file = NULL; char* config_file = NULL;
int arch = ARCH_X86;
int vblockonly = 0; int vblockonly = 0;
int verbose = 0; int verbose = 0;
uint64_t pad = DEFAULT_PADDING; uint64_t pad = DEFAULT_PADDING;
@@ -812,6 +829,17 @@ int main(int argc, char* argv[]) {
filename = optarg; filename = optarg;
break; 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: case OPT_OLDBLOB:
oldfile = optarg; oldfile = optarg;
break; break;
@@ -871,7 +899,7 @@ int main(int argc, char* argv[]) {
switch(mode) { switch(mode) {
case OPT_MODE_PACK: case OPT_MODE_PACK:
bp = NewBlob(version, vmlinuz, bootloader, config_file); bp = NewBlob(version, vmlinuz, bootloader, config_file, arch);
if (!bp) if (!bp)
return 1; return 1;
r = Pack(filename, key_block_file, signprivate, bp, pad, vblockonly); r = Pack(filename, key_block_file, signprivate, bp, pad, vblockonly);
@@ -892,7 +920,7 @@ int main(int argc, char* argv[]) {
r = ReplaceConfig(bp, config_file); r = ReplaceConfig(bp, config_file);
if (!r) { if (!r) {
if (version >= 0) { 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); r = Pack(filename, key_block_file, signprivate, bp, pad, vblockonly);
} }