summaryrefslogtreecommitdiff
path: root/kexec/arch/arm/kexec-zImage-arm.c
diff options
context:
space:
mode:
authorMika Westerberg <ext-mika.1.westerberg@nokia.com>2010-05-05 09:58:33 +0300
committerSimon Horman <horms@verge.net.au>2010-05-19 09:46:35 +0900
commitb1dcc08ea79ca96256a9ae6ef59e5ea4e217ef1d (patch)
tree0e2c68c0ae22c4e1ecec1efa16dc8b4bb3b4cb32 /kexec/arch/arm/kexec-zImage-arm.c
parent7429f91acaba453c819cc22b364a5f1339a275fd (diff)
kexec: implement ARM crashdump support
Implement support for loading dump capture kernels for ARM architecture. ARM doesn't need any backup memory regions so only elfcore header is allocated from the top of the reserved memory region. Only zImages are supported. The dump capture kernel needs to be loaded to physical address corresponding to the memory region reserved with 'crashkernel=size@start' kernel command line parameter. Signed-off-by: Mika Westerberg <ext-mika.1.westerberg@nokia.com> Signed-off-by: Simon Horman <horms@verge.net.au>
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;