diff options
-rw-r--r-- | kexec/arch/arm/include/arch/options.h | 12 | ||||
-rw-r--r-- | kexec/arch/arm/kexec-arm.c | 8 | ||||
-rw-r--r-- | kexec/arch/arm/kexec-zImage-arm.c | 20 |
3 files changed, 31 insertions, 9 deletions
diff --git a/kexec/arch/arm/include/arch/options.h b/kexec/arch/arm/include/arch/options.h index b355c26..b68b746 100644 --- a/kexec/arch/arm/include/arch/options.h +++ b/kexec/arch/arm/include/arch/options.h @@ -5,8 +5,9 @@ #define OPT_APPEND 'a' #define OPT_RAMDISK 'r' -#define OPT_DTB (OPT_ARCH_MAX+0) -#define OPT_ATAGS (OPT_ARCH_MAX+1) +#define OPT_DTB (OPT_ARCH_MAX+0) +#define OPT_ATAGS (OPT_ARCH_MAX+1) +#define OPT_IMAGE_SIZE (OPT_ARCH_MAX+2) /* Options relevant to the architecture (excluding loader-specific ones), * in this case none: @@ -37,8 +38,11 @@ { "initrd", 1, 0, OPT_RAMDISK }, \ { "ramdisk", 1, 0, OPT_RAMDISK }, \ { "dtb", 1, 0, OPT_DTB }, \ - { "atags", 0, 0, OPT_ATAGS }, + { "atags", 0, 0, OPT_ATAGS }, \ + { "image-size", 1, 0, OPT_IMAGE_SIZE }, -#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR "a:r:" +#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR "a:r:s:" + +extern unsigned int kexec_arm_image_size; #endif /* KEXEC_ARCH_ARM_OPTIONS_H */ diff --git a/kexec/arch/arm/kexec-arm.c b/kexec/arch/arm/kexec-arm.c index 8646833..6e8e320 100644 --- a/kexec/arch/arm/kexec-arm.c +++ b/kexec/arch/arm/kexec-arm.c @@ -81,9 +81,15 @@ struct file_type file_type[] = { }; int file_types = sizeof(file_type) / sizeof(file_type[0]); - void arch_usage(void) { + printf(" --image-size=<size>\n" + " Specify the assumed total image size of\n" + " the kernel that is about to be loaded,\n" + " including the .bss section, as reported\n" + " by 'arm-linux-size vmlinux'. If not\n" + " specified, this value is implicitly set\n" + " to the compressed images size * 4.\n"); } int arch_process_options(int argc, char **argv) diff --git a/kexec/arch/arm/kexec-zImage-arm.c b/kexec/arch/arm/kexec-zImage-arm.c index bb1b002..792187a 100644 --- a/kexec/arch/arm/kexec-zImage-arm.c +++ b/kexec/arch/arm/kexec-zImage-arm.c @@ -24,6 +24,7 @@ #define BOOT_PARAMS_SIZE 1536 off_t initrd_base = 0, initrd_size = 0; +unsigned int kexec_arm_image_size = 0; struct tag_header { uint32_t size; @@ -232,6 +233,7 @@ int zImage_arm_load(int argc, char **argv, const char *buf, off_t len, off_t dtb_length; char *dtb_file; off_t dtb_offset; + char *end; /* See options.h -- add any more there, too. */ static const struct option options[] = { @@ -242,6 +244,7 @@ int zImage_arm_load(int argc, char **argv, const char *buf, off_t len, { "ramdisk", 1, 0, OPT_RAMDISK }, { "dtb", 1, 0, OPT_DTB }, { "atags", 0, 0, OPT_ATAGS }, + { "image-size", 1, 0, OPT_IMAGE_SIZE }, { 0, 0, 0, 0 }, }; static const char short_options[] = KEXEC_ARCH_OPT_STR "a:r:"; @@ -275,6 +278,9 @@ int zImage_arm_load(int argc, char **argv, const char *buf, off_t len, case OPT_ATAGS: use_atags = 1; break; + case OPT_IMAGE_SIZE: + kexec_arm_image_size = strtoul(optarg, &end, 0); + break; } } @@ -337,10 +343,16 @@ int zImage_arm_load(int argc, char **argv, const char *buf, off_t len, if (base == ULONG_MAX) return -1; - /* assume the maximum kernel compression ratio is 4, - * and just to be safe, place ramdisk after that - */ - initrd_base = base + len * 4; + if (kexec_arm_image_size) { + /* If the image size was passed as command line argument, + * use that value for determining the address for initrd, + * atags and dtb images. page-align the given length.*/ + initrd_base = base + _ALIGN(kexec_arm_image_size, 4096); + } else { + /* Otherwise, assume the maximum kernel compression ratio + * is 4, and just to be safe, place ramdisk after that */ + initrd_base = base + len * 4; + } if (use_atags) { /* |