Hello Simon, From: Michael Holzheu <holzheu@xxxxxxxxxxxxxxxxxx> When the kernel image size is larger than 8 MiB on s390, we currently can't load the ramdisk, because it is loaded to the fix address 8 MiB (RAMDISK_ORIGIN_ADDR) per default. With this patch the ramdisk is loaded behind the image with an 1 MiB alignment. To be compatible with older kernels we still load the ramdisk to 8 MiB, if the kernel is smaller than 8 MiB. Signed-off-by: Michael Holzheu <holzheu at linux.vnet.ibm.com> --- kexec/arch/s390/kexec-image.c | 10 +++++++--- kexec/arch/s390/kexec-s390.h | 3 +++ 2 files changed, 10 insertions(+), 3 deletions(-) --- a/kexec/arch/s390/kexec-image.c +++ b/kexec/arch/s390/kexec-image.c @@ -101,16 +101,20 @@ image_s390_load(int argc, char **argv, c /* We do want to change the kernel image */ krnl_buffer = (void *) kernel_buf + IMAGE_READ_OFFSET; - /* Load ramdisk if present */ + /* + * Load ramdisk if present: If image is larger than RAMDISK_ORIGIN_ADDR, + * we load the ramdisk directly behind the image with 1 MiB alignment. + */ if (ramdisk) { rd_buffer = slurp_file(ramdisk, &ramdisk_len); if (rd_buffer == NULL) { fprintf(stderr, "Could not read ramdisk.\n"); return -1; } - ramdisk_origin = RAMDISK_ORIGIN_ADDR; + ramdisk_origin = MAX(RAMDISK_ORIGIN_ADDR, kernel_size); + ramdisk_origin = ALIGN_UP(ramdisk_origin, 0x100000); add_segment_check(info, rd_buffer, ramdisk_len, - RAMDISK_ORIGIN_ADDR, ramdisk_len); + ramdisk_origin, ramdisk_len); } if (info->kexec_flags & KEXEC_ON_CRASH) { if (load_crashdump_segments(info, crash_base, crash_end)) --- a/kexec/arch/s390/kexec-s390.h +++ b/kexec/arch/s390/kexec-s390.h @@ -21,6 +21,9 @@ #define COMMAND_LINESIZE 896 #define MAX_MEMORY_RANGES 64 +#define ALIGN_UP(addr, size) (((addr) + ((size)-1)) & (~((size)-1))) +#define MAX(x, y) ((x) > (y) ? (x) : (y)) + extern int image_s390_load(int, char **, const char *, off_t, struct kexec_info *); extern int image_s390_probe(const char *, off_t); extern void image_s390_usage(void);