[PATCH] kexec-tools: s390: Find correct address for ramdisk

Michael Holzheu holzheu at linux.vnet.ibm.com
Fri Sep 16 08:46:04 EDT 2011


Hello Simon,

From: Michael Holzheu <holzheu at linux.vnet.ibm.com>

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);





More information about the kexec mailing list