[PATCH 06/06] sh: Add vmlinux support
Magnus Damm
magnus.damm at gmail.com
Tue Aug 26 07:12:32 EDT 2008
From: Magnus Damm <damm at igel.co.jp>
Add SuperH vmlinux support through a zero-page aware elf loader. Only for
kexec at this point, in the future kdump support will be added.
Signed-off-by: Magnus Damm <damm at igel.co.jp>
---
kexec/arch/sh/Makefile | 1
kexec/arch/sh/kexec-elf-sh.c | 114 ++++++++++++++++++++++++++++++++++++++++++
kexec/arch/sh/kexec-sh.c | 1
kexec/arch/sh/kexec-sh.h | 5 +
4 files changed, 121 insertions(+)
--- 0004/kexec/arch/sh/Makefile
+++ work/kexec/arch/sh/Makefile 2008-08-22 13:17:18.000000000 +0900
@@ -4,6 +4,7 @@
sh_KEXEC_SRCS += kexec/arch/sh/kexec-sh.c
sh_KEXEC_SRCS += kexec/arch/sh/kexec-zImage-sh.c
sh_KEXEC_SRCS += kexec/arch/sh/kexec-netbsd-sh.c
+sh_KEXEC_SRCS += kexec/arch/sh/kexec-elf-sh.c
sh_KEXEC_SRCS += kexec/arch/sh/kexec-elf-rel-sh.c
sh_KEXEC_SRCS += kexec/arch/sh/netbsd_booter.S
--- /dev/null
+++ work/kexec/arch/sh/kexec-elf-sh.c 2008-08-22 14:24:31.000000000 +0900
@@ -0,0 +1,114 @@
+/*
+ * kexec: Linux boots Linux
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * Based on x86 implementation,
+ * Copyright (C) 2003-2005 Eric Biederman (ebiederm at xmission.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation (version 2 of the License).
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <elf.h>
+#include "../../kexec.h"
+#include "../../kexec-syscall.h"
+#include "../../kexec-elf.h"
+#include "../../kexec-elf-boot.h"
+#include <arch/options.h>
+#include "kexec-sh.h"
+
+int elf_sh_probe(const char *buf, off_t len)
+{
+ struct mem_ehdr ehdr;
+ int result;
+ result = build_elf_exec_info(buf, len, &ehdr, 0);
+ if (result < 0)
+ goto out;
+
+ /* Verify the architecuture specific bits */
+ if (ehdr.e_machine != EM_SH) {
+ result = -1;
+ goto out;
+ }
+
+ result = 0;
+ out:
+ free_elf_info(&ehdr);
+ return result;
+}
+
+void elf_sh_usage(void)
+{
+ printf(" --append=STRING Set the kernel command line to STRING\n"
+ );
+}
+
+int elf_sh_load(int argc, char **argv, const char *buf, off_t len,
+ struct kexec_info *info)
+{
+ struct mem_ehdr ehdr;
+ const char *command_line;
+ struct mem_sym sym;
+ int opt;
+ static const struct option options[] = {
+ KEXEC_ARCH_OPTIONS
+ { 0, 0, NULL, 0 },
+ };
+
+ static const char short_options[] = KEXEC_OPT_STR "";
+
+ /*
+ * Parse the command line arguments
+ */
+ command_line = 0;
+ 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;
+ }
+ }
+
+ /* Load the ELF executable */
+ elf_exec_build_load(info, &ehdr, buf, len, 0);
+ info->entry = (void *)ehdr.e_entry;
+
+ /* If we're booting a vmlinux then fill in empty_zero_page */
+ if (elf_rel_find_symbol(&ehdr, "empty_zero_page", &sym) == 0) {
+ unsigned char *zp = (void *)ehdr.e_shdr[sym.st_shndx].sh_data;
+
+ kexec_sh_setup_zero_page(zp, 4096, command_line);
+ }
+
+ return 0;
+}
--- 0005/kexec/arch/sh/kexec-sh.c
+++ work/kexec/arch/sh/kexec-sh.c 2008-08-22 13:17:18.000000000 +0900
@@ -53,6 +53,7 @@ int get_memory_ranges(struct memory_rang
/* Supported file types and callbacks */
struct file_type file_type[] = {
{"zImage-sh", zImage_sh_probe, zImage_sh_load, zImage_sh_usage},
+ {"elf-sh", elf_sh_probe, elf_sh_load, elf_sh_usage},
{"netbsd-sh", netbsd_sh_probe, netbsd_sh_load, netbsd_sh_usage},
};
int file_types = sizeof(file_type) / sizeof(file_type[0]);
--- 0005/kexec/arch/sh/kexec-sh.h
+++ work/kexec/arch/sh/kexec-sh.h 2008-08-22 13:17:18.000000000 +0900
@@ -6,6 +6,11 @@ int zImage_sh_load(int argc, char **argv
struct kexec_info *info);
void zImage_sh_usage(void);
+int elf_sh_probe(const char *buf, off_t len);
+int elf_sh_load(int argc, char **argv, const char *buf, off_t len,
+ struct kexec_info *info);
+void elf_sh_usage(void);
+
int netbsd_sh_probe(const char *buf, off_t len);
int netbsd_sh_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
More information about the kexec
mailing list