[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