summaryrefslogtreecommitdiff
path: root/kexec/arch/sh/kexec-zImage-sh.c
diff options
context:
space:
mode:
Diffstat (limited to 'kexec/arch/sh/kexec-zImage-sh.c')
-rw-r--r--kexec/arch/sh/kexec-zImage-sh.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/kexec/arch/sh/kexec-zImage-sh.c b/kexec/arch/sh/kexec-zImage-sh.c
new file mode 100644
index 0000000..9527fb6
--- /dev/null
+++ b/kexec/arch/sh/kexec-zImage-sh.c
@@ -0,0 +1,107 @@
+/*
+ * kexec-zImage-sh.c - kexec zImage loader for the SH
+ * Copyright (C) 2005 kogiidena@eggplant.ddo.jp
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#define _GNU_SOURCE
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <elf.h>
+#include <boot/elf_boot.h>
+#include <ip_checksum.h>
+#include "../../kexec.h"
+#include "../../kexec-elf.h"
+#include <arch/options.h>
+#include "kexec-sh.h"
+
+static const int probe_debug = 0;
+
+/*
+ * zImage_sh_probe - sanity check the elf image
+ *
+ * Make sure that the file image has a reasonable chance of working.
+ */
+int zImage_sh_probe(const char *buf, off_t len)
+{
+ if (memcmp(&buf[0x202], "HdrS", 4) != 0) {
+ fprintf(stderr, "Not a zImage\n");
+ return -1;
+ }
+ return 0;
+}
+
+void zImage_sh_usage(void)
+{
+ printf(
+
+ " --append=STRING Set the kernel command line to STRING.\n"
+ " --empty-zero=ADDRESS Set the kernel top ADDRESS. \n\n");
+
+}
+
+int zImage_sh_load(int argc, char **argv, const char *buf, off_t len,
+ struct kexec_info *info)
+{
+ char *command_line;
+ int opt;
+ unsigned long empty_zero, area;
+ unsigned char *param;
+ unsigned long *paraml;
+
+ static const struct option options[] = {
+ KEXEC_ARCH_OPTIONS
+ {0, 0, 0, 0},
+ };
+
+ static const char short_options[] = KEXEC_ARCH_OPT_STR "";
+
+ command_line = 0;
+ empty_zero = get_empty_zero(NULL);
+ while ((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) {
+ switch (opt) {
+ default:
+ /* Ignore core options */
+ if (opt < OPT_ARCH_MAX) {
+ break;
+ }
+ case '?':
+ usage();
+ return -1;
+ case OPT_APPEND:
+ command_line = optarg;
+ break;
+ case OPT_EMPTYZERO:
+ empty_zero = get_empty_zero(optarg);
+ break;
+ }
+ }
+ param = xmalloc(4096);
+ memset(param, 0, 4096);
+ area = empty_zero & 0x1c000000;
+ if (!command_line) {
+ command_line = get_append();
+ }
+ strncpy(&param[256], command_line, strlen(command_line));
+ paraml = (unsigned long *)param;
+ // paraml[0] = 1; // readonly flag is set as default
+
+ add_segment(info, param, 4096, empty_zero, 4096);
+ add_segment(info, buf, len, (area | 0x00210000), len);
+
+ /* For now we don't have arguments to pass :( */
+ info->entry = (void *)(0x80210000 | area);
+ return 0;
+}