summaryrefslogtreecommitdiff
path: root/kexec/arch/arm/kexec-zImage-arm.c
diff options
context:
space:
mode:
Diffstat (limited to 'kexec/arch/arm/kexec-zImage-arm.c')
-rw-r--r--kexec/arch/arm/kexec-zImage-arm.c47
1 files changed, 45 insertions, 2 deletions
diff --git a/kexec/arch/arm/kexec-zImage-arm.c b/kexec/arch/arm/kexec-zImage-arm.c
index 1a446d9..8e27956 100644
--- a/kexec/arch/arm/kexec-zImage-arm.c
+++ b/kexec/arch/arm/kexec-zImage-arm.c
@@ -12,10 +12,12 @@
#include <stdint.h>
#include <unistd.h>
#include <getopt.h>
+#include <unistd.h>
#include <arch/options.h>
#include "../../kexec.h"
+#include "../../kexec-syscall.h"
+#include "crashdump-arm.h"
-#define COMMAND_LINE_SIZE 1024
#define BOOT_PARAMS_SIZE 1536
struct tag_header {
@@ -213,6 +215,7 @@ int zImage_arm_load(int argc, char **argv, const char *buf, off_t len,
unsigned int atag_offset = 0x1000; /* 4k offset from memory start */
unsigned int offset = 0x8000; /* 32k offset from memory start */
const char *command_line;
+ char *modified_cmdline = NULL;
off_t command_line_len;
const char *ramdisk;
char *ramdisk_buf;
@@ -266,7 +269,47 @@ int zImage_arm_load(int argc, char **argv, const char *buf, off_t len,
ramdisk_buf = slurp_file(ramdisk, &ramdisk_length);
}
- base = locate_hole(info,len+offset,0,0,ULONG_MAX,INT_MAX);
+ /*
+ * If we are loading a dump capture kernel, we need to update kernel
+ * command line and also add some additional segments.
+ */
+ if (info->kexec_flags & KEXEC_ON_CRASH) {
+ uint64_t start, end;
+
+ modified_cmdline = xmalloc(COMMAND_LINE_SIZE);
+ if (!modified_cmdline)
+ return -1;
+
+ if (command_line) {
+ (void) strncpy(modified_cmdline, command_line,
+ COMMAND_LINE_SIZE);
+ modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0';
+ }
+
+ if (load_crashdump_segments(info, modified_cmdline) < 0) {
+ free(modified_cmdline);
+ return -1;
+ }
+
+ command_line = modified_cmdline;
+ command_line_len = strlen(command_line) + 1;
+
+ /*
+ * We put the dump capture kernel at the start of crashkernel
+ * reserved memory.
+ */
+ if (parse_iomem_single("Crash kernel\n", &start, &end)) {
+ /*
+ * No crash kernel memory reserved. We cannot do more
+ * but just bail out.
+ */
+ return -1;
+ }
+ base = start;
+ } else {
+ base = locate_hole(info,len+offset,0,0,ULONG_MAX,INT_MAX);
+ }
+
if (base == ULONG_MAX)
return -1;