diff options
Diffstat (limited to 'kexec/arch/sh/kexec-zImage-sh.c')
-rw-r--r-- | kexec/arch/sh/kexec-zImage-sh.c | 107 |
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(¶m[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; +} |