[OE-core] [PATCH 15/25] kexec-tools: add aarch64 support

Kai Kang kai.kang at windriver.com
Thu Nov 6 15:34:18 UTC 2014


Add patch from
https://fedorapeople.org/~hrw/aarch64/for-fedora/kexec-aarch64.patch

to add aarch64 support for kexec-tools.

Signed-off-by: Kai Kang <kai.kang at windriver.com>
---
 meta/recipes-kernel/kexec/kexec-tools.inc          |   2 +-
 .../kexec/kexec-tools/kexec-aarch64.patch          | 799 +++++++++++++++++++++
 meta/recipes-kernel/kexec/kexec-tools_2.0.7.bb     |   4 +-
 3 files changed, 803 insertions(+), 2 deletions(-)
 create mode 100644 meta/recipes-kernel/kexec/kexec-tools/kexec-aarch64.patch

diff --git a/meta/recipes-kernel/kexec/kexec-tools.inc b/meta/recipes-kernel/kexec/kexec-tools.inc
index 7e3b7ad..312424a 100644
--- a/meta/recipes-kernel/kexec/kexec-tools.inc
+++ b/meta/recipes-kernel/kexec/kexec-tools.inc
@@ -12,7 +12,7 @@ SRC_URI = "${KERNELORG_MIRROR}/linux/utils/kernel/kexec/kexec-tools-${PV}.tar.gz
 
 inherit autotools-brokensep
 
-COMPATIBLE_HOST = '(x86_64.*|i.86.*|arm.*|powerpc.*|mips.*)-(linux|freebsd.*)'
+COMPATIBLE_HOST = '(x86_64.*|i.86.*|arm.*|aarch64.*|powerpc.*|mips.*)-(linux|freebsd.*)'
 
 INSANE_SKIP_${PN} = "arch"
 
diff --git a/meta/recipes-kernel/kexec/kexec-tools/kexec-aarch64.patch b/meta/recipes-kernel/kexec/kexec-tools/kexec-aarch64.patch
new file mode 100644
index 0000000..8fe32d3
--- /dev/null
+++ b/meta/recipes-kernel/kexec/kexec-tools/kexec-aarch64.patch
@@ -0,0 +1,799 @@
+From: Geoff Levand <geoff at infradead.org>
+Date: Mon, 15 Jul 2013 23:32:36 +0000 (-0700)
+Subject: Add arm64 support
+X-Git-Url: https://git.linaro.org/gitweb?p=people%2Fgeoff%2Fkexec-tools.git;a=commitdiff_plain;h=fbf5ac6c2c70ec0f6da2b9ff563e573999752c01
+
+Add arm64 support
+
+Signed-off-by: Geoff Levand <geoff at infradead.org>
+
+Get patch from:
+https://fedorapeople.org/~hrw/aarch64/for-fedora/kexec-aarch64.patch
+
+Signed-off-by: Kai Kang <kai.kang at windriver.com>
+---
+
+Index: kexec-tools-2.0.4/configure.ac
+===================================================================
+--- kexec-tools-2.0.4.orig/configure.ac
++++ kexec-tools-2.0.4/configure.ac
+@@ -30,6 +30,9 @@ case $target_cpu in
+ 	powerpc64 )
+ 		ARCH="ppc64"
+ 		;;
++	aarch64 )
++		ARCH="arm64"
++		;;
+ 	arm* )
+ 		ARCH="arm"
+ 		;;
+Index: kexec-tools-2.0.4/kexec/Makefile
+===================================================================
+--- kexec-tools-2.0.4.orig/kexec/Makefile
++++ kexec-tools-2.0.4/kexec/Makefile
+@@ -70,6 +70,7 @@ KEXEC_SRCS			+= $($(ARCH)_FS2DT)
+ 
+ include $(srcdir)/kexec/arch/alpha/Makefile
+ include $(srcdir)/kexec/arch/arm/Makefile
++include $(srcdir)/kexec/arch/arm64/Makefile
+ include $(srcdir)/kexec/arch/i386/Makefile
+ include $(srcdir)/kexec/arch/ia64/Makefile
+ include $(srcdir)/kexec/arch/mips/Makefile
+Index: kexec-tools-2.0.4/kexec/arch/arm64/Makefile
+===================================================================
+--- /dev/null
++++ kexec-tools-2.0.4/kexec/arch/arm64/Makefile
+@@ -0,0 +1,13 @@
++
++arm64_KEXEC_SRCS += \
++	kexec/arch/arm64/kexec-arm64.c \
++	kexec/arch/arm64/kexec-elf-arm64.c \
++	kexec/arch/arm64/crashdump-arm64.c
++
++arm64_ARCH_REUSE_INITRD =
++arm64_ADD_SEGMENT =
++arm64_VIRT_TO_PHYS =
++
++dist += $(arm64_KEXEC_SRCS) \
++	kexec/arch/arm64/Makefile \
++	kexec/arch/arm64/kexec-arm64.h
+Index: kexec-tools-2.0.4/kexec/arch/arm64/crashdump-arm64.c
+===================================================================
+--- /dev/null
++++ kexec-tools-2.0.4/kexec/arch/arm64/crashdump-arm64.c
+@@ -0,0 +1,305 @@
++/*
++ * 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).
++ */
++
++#include "../../kexec.h"
++#include "../../kexec-elf.h"
++#include "../../crashdump.h"
++
++int is_crashkernel_mem_reserved(void)
++{
++	return 0;
++}
++
++#if 0
++/*
++ * Used to save various memory ranges/regions needed for the captured
++ * kernel to boot. (lime memmap= option in other archs)
++ */
++static struct memory_range crash_memory_ranges[CRASH_MAX_MEMORY_RANGES];
++struct memory_ranges usablemem_rgns = {
++    .size = 0,
++    .ranges = crash_memory_ranges,
++};
++
++/* memory range reserved for crashkernel */
++static struct memory_range crash_reserved_mem;
++
++static struct crash_elf_info elf_info = {
++	.class		= ELFCLASS32,
++	.data		= ELFDATA2LSB,
++	.machine	= EM_ARM,
++	.page_offset	= PAGE_OFFSET,
++};
++
++unsigned long phys_offset;
++
++/**
++ * crash_range_callback() - callback called for each iomem region
++ * @data: not used
++ * @nr: not used
++ * @str: name of the memory region
++ * @base: start address of the memory region
++ * @length: size of the memory region
++ *
++ * This function is called once for each memory region found in /proc/iomem. It
++ * locates system RAM and crashkernel reserved memory and places these to
++ * variables: @crash_memory_ranges and @crash_reserved_mem. Number of memory
++ * regions is placed in @crash_memory_nr_ranges.
++ */
++static int crash_range_callback(void *UNUSED(data), int UNUSED(nr),
++				char *str, unsigned long base,
++				unsigned long length)
++{
++	struct memory_range *range;
++
++	if (usablemem_rgns.size >= CRASH_MAX_MEMORY_RANGES)
++		return 1;
++
++	range = usablemem_rgns.ranges + usablemem_rgns.size;
++
++	if (strncmp(str, "System RAM\n", 11) == 0) {
++		range->start = base;
++		range->end = base + length - 1;
++		range->type = RANGE_RAM;
++		usablemem_rgns.size++;
++	} else if (strncmp(str, "Crash kernel\n", 13) == 0) {
++		crash_reserved_mem.start = base;
++		crash_reserved_mem.end = base + length - 1;
++		crash_reserved_mem.type = RANGE_RAM;
++	}
++
++	return 0;
++}
++
++/**
++ * crash_exclude_range() - excludes memory region reserved for crashkernel
++ *
++ * Function locates where crashkernel reserved memory is and removes that region
++ * from the available memory regions.
++ */
++static void crash_exclude_range(void)
++{
++	const struct memory_range *range = &crash_reserved_mem;
++	int i;
++
++	for (i = 0; i < usablemem_rgns.size; i++) {
++		struct memory_range *r = usablemem_rgns.ranges + i;
++
++		/*
++		 * We assume that crash area is fully contained in
++		 * some larger memory area.
++		 */
++		if (r->start <= range->start && r->end >= range->end) {
++			struct memory_range *new;
++			/*
++			 * Let's split this area into 2 smaller ones and
++			 * remove excluded range from between. First create
++			 * new entry for the remaining area.
++			 */
++			new = usablemem_rgns.ranges + usablemem_rgns.size;
++			new->start = range->end + 1;
++			new->end = r->end;
++			usablemem_rgns.size++;
++			/*
++			 * Next update this area to end before excluded range.
++			 */
++			r->end = range->start - 1;
++			break;
++		}
++	}
++}
++
++static int range_cmp(const void *a1, const void *a2)
++{
++	const struct memory_range *r1 = a1;
++	const struct memory_range *r2 = a2;
++
++	if (r1->start > r2->start)
++		return 1;
++	if (r1->start < r2->start)
++		return -1;
++
++	return 0;
++}
++
++/**
++ * crash_get_memory_ranges() - read system physical memory
++ *
++ * Function reads through system physical memory and stores found memory regions
++ * in @crash_memory_ranges. Number of memory regions found is placed in
++ * @crash_memory_nr_ranges. Regions are sorted in ascending order.
++ *
++ * Returns %0 in case of success and %-1 otherwise (errno is set).
++ */
++static int crash_get_memory_ranges(void)
++{
++	/*
++	 * First read all memory regions that can be considered as
++	 * system memory including the crash area.
++	 */
++	kexec_iomem_for_each_line(NULL, crash_range_callback, NULL);
++
++	if (usablemem_rgns.size < 1) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	/*
++	 * Exclude memory reserved for crashkernel (this may result a split memory
++	 * region).
++	 */
++	crash_exclude_range();
++
++	/*
++	 * Make sure that the memory regions are sorted.
++	 */
++	qsort(usablemem_rgns.ranges, usablemem_rgns.size,
++	      sizeof(*usablemem_rgns.ranges), range_cmp);
++
++	return 0;
++}
++
++/**
++ * cmdline_add_elfcorehdr() - adds elfcorehdr= to @cmdline
++ * @cmdline: buffer where parameter is placed
++ * @elfcorehdr: physical address of elfcorehdr
++ *
++ * Function appends 'elfcorehdr=start' at the end of the command line given in
++ * @cmdline. Note that @cmdline must be at least %COMMAND_LINE_SIZE bytes long
++ * (inclunding %NUL).
++ */
++static void cmdline_add_elfcorehdr(char *cmdline, unsigned long elfcorehdr)
++{
++	char buf[COMMAND_LINE_SIZE];
++	int buflen;
++
++	buflen = snprintf(buf, sizeof(buf), "%s elfcorehdr=%#lx",
++			  cmdline, elfcorehdr);
++	if (buflen < 0)
++		die("Failed to construct elfcorehdr= command line parameter\n");
++	if (buflen >= sizeof(buf))
++		die("Command line overflow\n");
++
++	(void) strncpy(cmdline, buf, COMMAND_LINE_SIZE);
++	cmdline[COMMAND_LINE_SIZE - 1] = '\0';
++}
++
++/**
++ * cmdline_add_mem() - adds mem= parameter to kernel command line
++ * @cmdline: buffer where parameter is placed
++ * @size: size of the kernel reserved memory (in bytes)
++ *
++ * This function appends 'mem=size' at the end of the command line given in
++ * @cmdline. Note that @cmdline must be at least %COMMAND_LINE_SIZE bytes long
++ * (including %NUL).
++ */
++static void cmdline_add_mem(char *cmdline, unsigned long size)
++{
++	char buf[COMMAND_LINE_SIZE];
++	int buflen;
++
++	buflen = snprintf(buf, sizeof(buf), "%s mem=%ldK", cmdline, size >> 10);
++	if (buflen < 0)
++		die("Failed to construct mem= command line parameter\n");
++	if (buflen >= sizeof(buf))
++		die("Command line overflow\n");
++
++	(void) strncpy(cmdline, buf, COMMAND_LINE_SIZE);
++	cmdline[COMMAND_LINE_SIZE - 1] = '\0';
++}
++
++static unsigned long long range_size(const struct memory_range *r)
++{
++	return r->end - r->start + 1;
++}
++
++static void dump_memory_ranges(void)
++{
++	int i;
++
++	if (!kexec_debug)
++		return;
++
++	dbgprintf("crashkernel: [%#llx - %#llx] (%ldM)\n",
++		  crash_reserved_mem.start, crash_reserved_mem.end,
++		  (unsigned long)range_size(&crash_reserved_mem) >> 20);
++
++	for (i = 0; i < usablemem_rgns.size; i++) {
++		struct memory_range *r = usablemem_rgns.ranges + i;
++		dbgprintf("memory range: [%#llx - %#llx] (%ldM)\n",
++			  r->start, r->end, (unsigned long)range_size(r) >> 20);
++	}
++}
++
++/**
++ * load_crashdump_segments() - loads additional segments needed for kdump
++ * @info: kexec info structure
++ * @mod_cmdline: kernel command line
++ *
++ * This function loads additional segments which are needed for the dump capture
++ * kernel. It also updates kernel command line passed in @mod_cmdline to have
++ * right parameters for the dump capture kernel.
++ *
++ * Return %0 in case of success and %-1 in case of error.
++ */
++int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline)
++{
++	unsigned long elfcorehdr;
++	unsigned long bufsz;
++	void *buf;
++	int err;
++
++	/*
++	 * First fetch all the memory (RAM) ranges that we are going to pass to
++	 * the crashdump kernel during panic.
++	 */
++	err = crash_get_memory_ranges();
++	if (err)
++		return err;
++
++	/*
++	 * Now that we have memory regions sorted, we can use first memory
++	 * region as PHYS_OFFSET.
++	 */
++	phys_offset = usablemem_rgns.ranges->start;
++	dbgprintf("phys_offset: %#lx\n", phys_offset);
++
++	err = crash_create_elf32_headers(info, &elf_info,
++					 usablemem_rgns.ranges,
++					 usablemem_rgns.size, &buf, &bufsz,
++					 ELF_CORE_HEADER_ALIGN);
++	if (err)
++		return err;
++
++	/*
++	 * We allocate ELF core header from the end of the memory area reserved
++	 * for the crashkernel. We align the header to SECTION_SIZE (which is
++	 * 1MB) so that available memory passed in kernel command line will be
++	 * aligned to 1MB. This is because kernel create_mapping() wants memory
++	 * regions to be aligned to SECTION_SIZE.
++	 */
++	elfcorehdr = add_buffer_phys_virt(info, buf, bufsz, bufsz, 1 << 20,
++					  crash_reserved_mem.start,
++					  crash_reserved_mem.end, -1, 0);
++
++	dbgprintf("elfcorehdr: %#lx\n", elfcorehdr);
++	cmdline_add_elfcorehdr(mod_cmdline, elfcorehdr);
++
++	/*
++	 * Add 'mem=size' parameter to dump capture kernel command line. This
++	 * prevents the dump capture kernel from using any other memory regions
++	 * which belong to the primary kernel.
++	 */
++	cmdline_add_mem(mod_cmdline, elfcorehdr - crash_reserved_mem.start);
++
++	dump_memory_ranges();
++	dbgprintf("kernel command line: \"%s\"\n", mod_cmdline);
++
++	return 0;
++}
++
++#endif
++
+Index: kexec-tools-2.0.4/kexec/arch/arm64/include/arch/options.h
+===================================================================
+--- /dev/null
++++ kexec-tools-2.0.4/kexec/arch/arm64/include/arch/options.h
+@@ -0,0 +1,26 @@
++#ifndef KEXEC_ARCH_ARM64_OPTIONS_H
++#define KEXEC_ARCH_ARM64_OPTIONS_H
++
++//#define OPT_ARCH_MAX	((OPT_MAX)+0)
++
++#define OPT_APPEND	((OPT_MAX)+0)
++#define OPT_RAMDISK	((OPT_MAX)+1)
++#define OPT_DTB		((OPT_MAX)+2)
++
++#define OPT_ARCH_MAX	((OPT_MAX)+3)
++
++
++#define KEXEC_ARCH_OPTIONS \
++	KEXEC_OPTIONS \
++	{ "append",       1, NULL, OPT_APPEND }, \
++	{ "command-line", 1, NULL, OPT_APPEND }, \
++	{ "dtb",          1, NULL, OPT_DTB }, \
++	{ "initrd",       1, NULL, OPT_RAMDISK }, \
++	{ "ramdisk",      1, NULL, OPT_RAMDISK }, \
++
++#define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR /* Only accept long arch options. */
++
++#define KEXEC_ALL_OPTIONS KEXEC_ARCH_OPTIONS
++#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR
++
++#endif /* KEXEC_ARCH_ARM64_OPTIONS_H */
+Index: kexec-tools-2.0.4/kexec/arch/arm64/kexec-arm64.c
+===================================================================
+--- /dev/null
++++ kexec-tools-2.0.4/kexec/arch/arm64/kexec-arm64.c
+@@ -0,0 +1,177 @@
++/*
++ * ARM64 kexec support.
++ */
++
++#define _GNU_SOURCE
++
++#include <errno.h>
++#include <stddef.h>
++
++//#include <linux/kexec.h>
++
++#include "../../kexec.h"
++#include "../../kexec-syscall.h"
++#include "kexec-arm64.h"
++
++
++void arch_usage(void)
++{
++	fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
++
++	printf(
++"     --append=STRING       Set the kernel command line to STRING.\n"
++"     --command-line=STRING Set the kernel command line to STRING.\n"
++"     --dtb=FILE            Use FILE as the device tree blob.\n"
++"     --initrd=FILE         Use FILE as the kernel initial ramdisk.\n"
++"     --ramdisk=FILE        Use FILE as the kernel initial ramdisk.\n");
++
++	fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
++}
++
++int arch_process_options(int UNUSED(argc), char **UNUSED(argv))
++{
++	fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
++	return 0;
++}
++
++const struct arch_map_entry arches[] = {
++	{ "aarch64", KEXEC_ARCH_ARM64 },
++	{ NULL, 0 },
++};
++
++void arch_update_purgatory(struct kexec_info *UNUSED(info))
++{
++	fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
++}
++
++unsigned long virt_to_phys(unsigned long addr)
++{
++	fprintf(stderr, "%s:%d: %016lx -> %016lx\n", __func__, __LINE__, addr,
++		addr + 0x080000000UL);
++	return addr + 0x080000000UL;
++}
++
++void add_segment(struct kexec_info *info, const void *buf, size_t bufsz,
++	unsigned long base, size_t memsz)
++{
++	fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
++	add_segment_phys_virt(info, buf, bufsz, base, memsz, 1);
++	fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
++}
++
++static int get_memory_ranges_1(struct memory_range **range, int *ranges,
++			unsigned long kexec_flags)
++{
++	static struct memory_range memory_range[KEXEC_SEGMENT_MAX];
++	const char *iomem;
++	int range_count = 0;
++	char line[MAX_LINE];
++	FILE *fp;
++
++	iomem = proc_iomem();
++	fp = fopen(iomem, "r");
++
++	if (!fp) {
++		fprintf(stderr, "Cannot open %s: %s\n",
++			iomem, strerror(errno));
++		return -1;
++	}
++
++	dbgprintf("memory ranges:\n");
++
++	while(fgets(line, sizeof(line), fp) != 0) {
++		struct memory_range r;
++		char *str;
++		int consumed;
++
++		if (range_count >= KEXEC_SEGMENT_MAX)
++			break;
++
++		if (sscanf(line, "%Lx-%Lx : %n", &r.start, &r.end, &consumed)
++			!= 2)
++			continue;
++
++		str = line + consumed;
++		r.end++;
++
++		if (memcmp(str, "System RAM\n", 11)) {
++			dbgprintf(" Skip: %016Lx - %016Lx : %s", r.start, r.end,
++				str);
++			continue;
++		}
++
++		r.type = RANGE_RAM;
++		memory_range[range_count] = r;
++		range_count++;
++
++		dbgprintf(" Add:  %016Lx - %016Lx : %s", r.start, r.end, str);
++	}
++
++	fclose(fp);
++	*range = memory_range;
++	*ranges = range_count;
++
++	return 0;
++}
++
++static int get_memory_ranges_2(struct memory_range **range, int *ranges,
++		      unsigned long UNUSED(kexec_flags))
++{
++	static struct memory_range memory_range[2];
++
++	memory_range[0].start = 0x080000000;
++	memory_range[0].end   = 0x100000000;
++	memory_range[0].type = RANGE_RAM;
++
++	memory_range[1].start = 0x900000000;
++	memory_range[1].end   = 0x880000000;
++	memory_range[1].type = RANGE_RAM;
++
++	*range = memory_range;
++	*ranges = sizeof(memory_range) / sizeof(memory_range[0]);
++
++	return 0;
++}
++
++int get_memory_ranges(struct memory_range **range, int *ranges,
++			unsigned long kexec_flags)
++{
++	/* FIXME: Should get this info from device tree. */
++	
++	return get_memory_ranges_1(range, ranges, kexec_flags);
++}
++
++struct file_type file_type[] = {
++	{ "elf-arm64", elf_arm64_probe, elf_arm64_load, elf_arm64_usage },
++};
++
++int file_types = sizeof(file_type) / sizeof(file_type[0]);
++
++int arch_compat_trampoline(struct kexec_info *info)
++{
++	fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
++	return 0;
++}
++
++void arch_reuse_initrd(void)
++{
++}
++
++int machine_verify_elf_rel(struct mem_ehdr *ehdr)
++{
++	(void)ehdr;
++
++	fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
++	return 0;
++}
++
++void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type,
++	void *location, unsigned long address, unsigned long value)
++{
++	(void)ehdr;
++	(void)r_type;
++	(void)location;
++	(void)address;
++	(void)value;
++	fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
++}
+Index: kexec-tools-2.0.4/kexec/arch/arm64/kexec-arm64.h
+===================================================================
+--- /dev/null
++++ kexec-tools-2.0.4/kexec/arch/arm64/kexec-arm64.h
+@@ -0,0 +1,20 @@
++/*
++ * ARM64 kexec support.
++ */
++
++#if !defined(KEXEC_ARM64_H)
++#define KEXEC_ARM64_H
++
++/* #include <linux/kexec.h> FIXME: this is broken */
++#include <sys/types.h>
++
++#include "../../kexec.h"
++
++#define KEXEC_SEGMENT_MAX 16 /* FIXME: this should come from <linux/kexec.h> */
++
++int elf_arm64_probe(const char *buf, off_t len);
++int elf_arm64_load(int argc, char **argv, const char *buf, off_t len,
++	struct kexec_info *info);
++void elf_arm64_usage(void);
++
++#endif
+\ No newline at end of file
+Index: kexec-tools-2.0.4/kexec/arch/arm64/kexec-elf-arm64.c
+===================================================================
+--- /dev/null
++++ kexec-tools-2.0.4/kexec/arch/arm64/kexec-elf-arm64.c
+@@ -0,0 +1,114 @@
++/*
++ * ARM64 kexec support.
++ */
++
++#define _GNU_SOURCE
++
++#include <elf.h>
++#include <getopt.h>
++
++#include "../../kexec-syscall.h"
++
++#include "kexec-arm64.h"
++#include "arch/options.h"
++
++#if !defined(EM_AARCH64)
++# define EM_AARCH64 183
++#endif
++
++int elf_arm64_probe(const char *buf, off_t len)
++{
++	int result;
++	struct mem_ehdr ehdr;
++
++	fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
++	
++	result = build_elf_exec_info(buf, len, &ehdr, 0);
++
++	if (result < 0) {
++		dbgprintf("Not an ELF executable\n");
++		goto out;
++	}
++
++	if (ehdr.e_machine != EM_AARCH64) {
++		dbgprintf("Not an AARCH64 executable\n");
++		result = -1;
++		goto out;
++	}
++
++	result = 0;
++
++out:
++	free_elf_info(&ehdr);
++	fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
++	return result;
++}
++
++int elf_arm64_load(int argc, char **argv, const char *buf, off_t len,
++			struct kexec_info *info)
++{
++	static const struct option options[] = {
++		KEXEC_ARCH_OPTIONS
++		{ 0 }
++	};
++	static const char short_options[] = KEXEC_OPT_STR "";
++	const char *command_line = NULL;
++	unsigned int command_line_len = 0;
++	const char *ramdisk = NULL;
++	const char *dtb = NULL;
++	int opt;
++	struct mem_ehdr ehdr;
++	int result;
++
++	fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
++
++	while ((opt = getopt_long(argc, argv, short_options, options, 0))
++		!= -1) {
++		switch (opt) {
++		default:
++			if (opt < OPT_MAX) /* Ignore core options */
++				break;
++		case OPT_APPEND:
++			command_line = optarg;
++			command_line_len = strlen(command_line) + 1;
++			break;
++		case OPT_RAMDISK:
++			ramdisk = optarg;
++			break;
++		case OPT_DTB:
++			dtb = optarg;
++			break;
++		}
++	}
++
++	fprintf(stderr, "%s:%d: command_line: %s\n", __func__, __LINE__, command_line);
++	fprintf(stderr, "%s:%d: ramdisk: %s\n", __func__, __LINE__, ramdisk);
++	fprintf(stderr, "%s:%d: dtb: %s\n", __func__, __LINE__, dtb);
++
++	if (info->kexec_flags & KEXEC_ON_CRASH) {
++		fprintf(stderr, "kexec: kdump not yet supported on arm64\n");
++		return -1;
++	}
++
++	result = build_elf_exec_info(buf, len, &ehdr, 0);
++
++	if (result < 0) {
++		free_elf_info(&ehdr);
++		fprintf(stderr, "%s:%d: free_elf_info failed\n", __func__,
++			__LINE__);
++		return result;
++	}
++
++	elf_exec_build_load(info, &ehdr, buf, len, 0);
++
++	info->entry = (void*)0x80080000UL;  // FIXME
++
++	fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
++	return 0;
++}
++
++void elf_arm64_usage(void)
++{
++	fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
++	fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
++}
+Index: kexec-tools-2.0.4/kexec/kexec-syscall.h
+===================================================================
+--- kexec-tools-2.0.4.orig/kexec/kexec-syscall.h
++++ kexec-tools-2.0.4/kexec/kexec-syscall.h
+@@ -39,8 +39,8 @@
+ #ifdef __s390__
+ #define __NR_kexec_load		277
+ #endif
+-#ifdef __arm__
+-#define __NR_kexec_load		__NR_SYSCALL_BASE + 347  
++#if defined(__arm__) || defined(__arm64__)
++#define __NR_kexec_load		__NR_SYSCALL_BASE + 347
+ #endif
+ #if defined(__mips__)
+ #define __NR_kexec_load                4311
+@@ -72,6 +72,8 @@ static inline long kexec_load(void *entr
+ #define KEXEC_ARCH_PPC64   (21 << 16)
+ #define KEXEC_ARCH_IA_64   (50 << 16)
+ #define KEXEC_ARCH_ARM     (40 << 16)
++#define KEXEC_ARCH_ARM64   (183 << 16)
++/* #define KEXEC_ARCH_AARCH64 (183 << 16) */
+ #define KEXEC_ARCH_S390    (22 << 16)
+ #define KEXEC_ARCH_SH      (42 << 16)
+ #define KEXEC_ARCH_MIPS_LE (10 << 16)
+@@ -114,5 +116,8 @@ static inline long kexec_load(void *entr
+ #if defined(__mips__)
+ #define KEXEC_ARCH_NATIVE	KEXEC_ARCH_MIPS
+ #endif
++#if defined(__arm64__)
++#define KEXEC_ARCH_NATIVE	KEXEC_ARCH_ARM64
++#endif
+ 
+ #endif /* KEXEC_SYSCALL_H */
+Index: kexec-tools-2.0.4/kexec/kexec.c
+===================================================================
+--- kexec-tools-2.0.4.orig/kexec/kexec.c
++++ kexec-tools-2.0.4/kexec/kexec.c
+@@ -659,6 +659,8 @@ static int my_load(const char *type, int
+ 	info.backup_start = 0;
+ 	info.kexec_flags = kexec_flags;
+ 
++	fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
++
+ 	result = 0;
+ 	if (argc - fileind <= 0) {
+ 		fprintf(stderr, "No kernel specified\n");
+Index: kexec-tools-2.0.4/purgatory/arch/arm64/Makefile
+===================================================================
+--- /dev/null
++++ kexec-tools-2.0.4/purgatory/arch/arm64/Makefile
+@@ -0,0 +1,7 @@
++#
++# Purgatory arm64
++#
++
++arm64_PURGATORY_SRCS =
++
++dist += purgatory/arch/arm64/Makefile $(arm64_PURGATORY_SRCS)
+Index: kexec-tools-2.0.4/configure
+===================================================================
+--- kexec-tools-2.0.4.orig/configure
++++ kexec-tools-2.0.4/configure
+@@ -2256,6 +2256,9 @@ case $target_cpu in
+ 	powerpc64 )
+ 		ARCH="ppc64"
+ 		;;
++	aarch64 )
++		ARCH="arm64"
++		;;
+ 	arm* )
+ 		ARCH="arm"
+ 		;;
diff --git a/meta/recipes-kernel/kexec/kexec-tools_2.0.7.bb b/meta/recipes-kernel/kexec/kexec-tools_2.0.7.bb
index f0ece0d..2f87321 100644
--- a/meta/recipes-kernel/kexec/kexec-tools_2.0.7.bb
+++ b/meta/recipes-kernel/kexec/kexec-tools_2.0.7.bb
@@ -2,7 +2,9 @@ require kexec-tools.inc
 export LDFLAGS = "-L${STAGING_LIBDIR}"
 EXTRA_OECONF = " --with-zlib=yes"
 
-SRC_URI += "file://kexec-tools-Refine-kdump-device_tree-sort.patch"
+SRC_URI += "file://kexec-tools-Refine-kdump-device_tree-sort.patch \
+            file://kexec-aarch64.patch \
+           "
 
 SRC_URI[md5sum] = "2309ba43981cb6d39d07ac3a9aac30ab"
 SRC_URI[sha256sum] = "dde5c38be39882c6c91f0129647349c4e1943b077d3020af1970b481ee954eb0"
-- 
1.9.1




More information about the Openembedded-core mailing list