[OE-core] [PATCH v3 1/1] kexec-tools: Upgrade to 2.0.14

zhe.he at windriver.com zhe.he at windriver.com
Thu Dec 29 02:06:30 UTC 2016


From: He Zhe <zhe.he at windriver.com>

Remove kexec-aarch64.patch since it has been merged upstream
Remove kexec-x32.patch since it has been reverted upstream
Add patches for kdump arm64 from upstream mailing list:
http://lists.infradead.org/pipermail/kexec/2016-November/017555.html

Signed-off-by: He Zhe <zhe.he at windriver.com>
---
 ...nd-the-semantics-of-kexec_iomem_for_each_.patch |  78 ++
 ...eneralize-and-rename-get_kernel_stext_sym.patch | 194 +++++
 ...0003-arm64-identify-PHYS_OFFSET-correctly.patch |  76 ++
 .../0004-arm64-kdump-identify-memory-regions.patch | 202 ++++++
 ...5-arm64-kdump-add-elf-core-header-segment.patch | 191 +++++
 ...6-arm64-kdump-set-up-kernel-image-segment.patch | 137 ++++
 .../0007-arm64-kdump-set-up-other-segments.patch   |  35 +
 ...-add-DT-properties-to-crash-dump-kernel-s.patch | 150 ++++
 ...-kdump-Add-support-for-binary-image-files.patch |  52 ++
 .../kexec/kexec-tools/kexec-aarch64.patch          | 801 ---------------------
 .../kexec/kexec-tools/kexec-x32.patch              |  88 ---
 ...kexec-tools_2.0.12.bb => kexec-tools_2.0.14.bb} |  15 +-
 12 files changed, 1126 insertions(+), 893 deletions(-)
 create mode 100644 meta/recipes-kernel/kexec/kexec-tools/0001-kexec-exntend-the-semantics-of-kexec_iomem_for_each_.patch
 create mode 100644 meta/recipes-kernel/kexec/kexec-tools/0002-kexec-generalize-and-rename-get_kernel_stext_sym.patch
 create mode 100644 meta/recipes-kernel/kexec/kexec-tools/0003-arm64-identify-PHYS_OFFSET-correctly.patch
 create mode 100644 meta/recipes-kernel/kexec/kexec-tools/0004-arm64-kdump-identify-memory-regions.patch
 create mode 100644 meta/recipes-kernel/kexec/kexec-tools/0005-arm64-kdump-add-elf-core-header-segment.patch
 create mode 100644 meta/recipes-kernel/kexec/kexec-tools/0006-arm64-kdump-set-up-kernel-image-segment.patch
 create mode 100644 meta/recipes-kernel/kexec/kexec-tools/0007-arm64-kdump-set-up-other-segments.patch
 create mode 100644 meta/recipes-kernel/kexec/kexec-tools/0008-arm64-kdump-add-DT-properties-to-crash-dump-kernel-s.patch
 create mode 100644 meta/recipes-kernel/kexec/kexec-tools/0009-arm64-kdump-Add-support-for-binary-image-files.patch
 delete mode 100644 meta/recipes-kernel/kexec/kexec-tools/kexec-aarch64.patch
 delete mode 100644 meta/recipes-kernel/kexec/kexec-tools/kexec-x32.patch
 rename meta/recipes-kernel/kexec/{kexec-tools_2.0.12.bb => kexec-tools_2.0.14.bb} (55%)

diff --git a/meta/recipes-kernel/kexec/kexec-tools/0001-kexec-exntend-the-semantics-of-kexec_iomem_for_each_.patch b/meta/recipes-kernel/kexec/kexec-tools/0001-kexec-exntend-the-semantics-of-kexec_iomem_for_each_.patch
new file mode 100644
index 0000000..dc8f9b1
--- /dev/null
+++ b/meta/recipes-kernel/kexec/kexec-tools/0001-kexec-exntend-the-semantics-of-kexec_iomem_for_each_.patch
@@ -0,0 +1,78 @@
+From 02eed0f8f2748fd7579f69e5373445b52b2b8754 Mon Sep 17 00:00:00 2001
+From: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Date: Mon, 17 Oct 2016 13:56:58 +0900
+Subject: [PATCH 1/9] kexec: exntend the semantics of kexec_iomem_for_each_line
+
+The current kexec_iomem_for_each_line() counts up all the lines for which
+a callback function returns zero(0) or positive, and otherwise it stops
+further scanning.
+This behavior is incovenient in some cases. For instance, on arm64, we want
+to count up "System RAM" entries, but need to skip "reserved" entries.
+
+So this patch extends the semantics so that we will continue to scan
+succeeding entries but not count lines for which a callback function
+returns positive.
+
+The current users of kexec_iomem_for_each_line(), arm, sh and x86, will not
+be affected by this change because
+* arm
+  The callback function only returns -1 or 0, and the return value of
+  kexec_iomem_for_each_line() will never be used.
+* sh, x86
+  The callback function may return (-1 for sh,) 0 or 1, but always returns
+  1 once we have reached the maximum number of entries allowed.
+  Even so the current kexec_iomem_for_each_line() counts them up.
+  This change actually fixes this bug.
+
+Upstream-Status: Submitted [http://lists.infradead.org/pipermail/kexec/2016-November/017556.html]
+
+Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Signed-off-by: He Zhe <zhe.he at windriver.com>
+---
+ kexec/kexec-iomem.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/kexec/kexec-iomem.c b/kexec/kexec-iomem.c
+index 485a2e8..0a0277a 100644
+--- a/kexec/kexec-iomem.c
++++ b/kexec/kexec-iomem.c
+@@ -18,6 +18,9 @@
+  * Iterate over each line in the file returned by proc_iomem(). If match is
+  * NULL or if the line matches with our match-pattern then call the
+  * callback if non-NULL.
++ * If match is NULL, callback should return a negative if error.
++ * Otherwise the interation goes on, incrementing nr but only if callback
++ * returns 0 (matched).
+  *
+  * Return the number of lines matched.
+  */
+@@ -37,7 +40,7 @@ int kexec_iomem_for_each_line(char *match,
+ 	char *str;
+ 	int consumed;
+ 	int count;
+-	int nr = 0;
++	int nr = 0, ret;
+ 
+ 	fp = fopen(iomem, "r");
+ 	if (!fp)
+@@ -50,11 +53,13 @@ int kexec_iomem_for_each_line(char *match,
+ 		str = line + consumed;
+ 		size = end - start + 1;
+ 		if (!match || memcmp(str, match, strlen(match)) == 0) {
+-			if (callback
+-			    && callback(data, nr, str, start, size) < 0) {
+-				break;
++			if (callback) {
++				ret = callback(data, nr, str, start, size);
++				if (ret < 0)
++					break;
++				else if (ret == 0)
++					nr++;
+ 			}
+-			nr++;
+ 		}
+ 	}
+ 
+-- 
+1.9.1
+
diff --git a/meta/recipes-kernel/kexec/kexec-tools/0002-kexec-generalize-and-rename-get_kernel_stext_sym.patch b/meta/recipes-kernel/kexec/kexec-tools/0002-kexec-generalize-and-rename-get_kernel_stext_sym.patch
new file mode 100644
index 0000000..ac95ad5
--- /dev/null
+++ b/meta/recipes-kernel/kexec/kexec-tools/0002-kexec-generalize-and-rename-get_kernel_stext_sym.patch
@@ -0,0 +1,194 @@
+From d29f37bb6e9114aba96c606103b110f511bee9a1 Mon Sep 17 00:00:00 2001
+From: Pratyush Anand <panand at redhat.com>
+Date: Wed, 2 Nov 2016 15:05:25 +0530
+Subject: [PATCH 2/9] kexec: generalize and rename get_kernel_stext_sym()
+
+get_kernel_stext_sym() has been defined for both arm and i386. Other
+architecture might need some other kernel symbol address. Therefore rewrite
+this function as generic function to get any kernel symbol address.
+
+More over, kallsyms is not arch specific representation, therefore have
+common function for all arches.
+
+Upstream-Status: Submitted [http://lists.infradead.org/pipermail/kexec/2016-November/017579.html]
+
+Signed-off-by: Pratyush Anand <panand at redhat.com>
+[created symbols.c]
+Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Signed-off-by: He Zhe <zhe.he at windriver.com>
+---
+ kexec/Makefile                  |  1 +
+ kexec/arch/arm/crashdump-arm.c  | 40 +---------------------------------------
+ kexec/arch/i386/crashdump-x86.c | 29 -----------------------------
+ kexec/kexec.h                   |  2 ++
+ kexec/symbols.c                 | 41 +++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 45 insertions(+), 68 deletions(-)
+ create mode 100644 kexec/symbols.c
+
+diff --git a/kexec/Makefile b/kexec/Makefile
+index 39f365f..2b4fb3d 100644
+--- a/kexec/Makefile
++++ b/kexec/Makefile
+@@ -26,6 +26,7 @@ KEXEC_SRCS_base += kexec/kernel_version.c
+ KEXEC_SRCS_base += kexec/lzma.c
+ KEXEC_SRCS_base += kexec/zlib.c
+ KEXEC_SRCS_base += kexec/kexec-xen.c
++KEXEC_SRCS_base += kexec/symbols.c
+ 
+ KEXEC_GENERATED_SRCS += $(PURGATORY_HEX_C)
+ 
+diff --git a/kexec/arch/arm/crashdump-arm.c b/kexec/arch/arm/crashdump-arm.c
+index 4a89b5e..245c21a 100644
+--- a/kexec/arch/arm/crashdump-arm.c
++++ b/kexec/arch/arm/crashdump-arm.c
+@@ -73,48 +73,10 @@ static struct crash_elf_info elf_info = {
+ 
+ extern unsigned long long user_page_offset;
+ 
+-/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */
+-static unsigned long long get_kernel_stext_sym(void)
+-{
+-	const char *kallsyms = "/proc/kallsyms";
+-	const char *stext = "_stext";
+-	char sym[128];
+-	char line[128];
+-	FILE *fp;
+-	unsigned long long vaddr = 0;
+-	char type;
+-
+-	fp = fopen(kallsyms, "r");
+-	if (!fp) {
+-		fprintf(stderr, "Cannot open %s\n", kallsyms);
+-		return 0;
+-	}
+-
+-	while(fgets(line, sizeof(line), fp) != NULL) {
+-		unsigned long long addr;
+-
+-		if (sscanf(line, "%Lx %c %s", &addr, &type, sym) != 3)
+-			continue;
+-
+-		if (strcmp(sym, stext) == 0) {
+-			dbgprintf("kernel symbol %s vaddr = %#llx\n", stext, addr);
+-			vaddr = addr;
+-			break;
+-		}
+-	}
+-
+-	fclose(fp);
+-
+-	if (vaddr == 0)
+-		fprintf(stderr, "Cannot get kernel %s symbol address\n", stext);
+-
+-	return vaddr;
+-}
+-
+ static int get_kernel_page_offset(struct kexec_info *info,
+ 		struct crash_elf_info *elf_info)
+ {
+-	unsigned long long stext_sym_addr = get_kernel_stext_sym();
++	unsigned long long stext_sym_addr = get_kernel_sym("_stext");
+ 	if (stext_sym_addr == 0) {
+ 		if (user_page_offset != (-1ULL)) {
+ 			elf_info->page_offset = user_page_offset;
+diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
+index ab833d4..abf82a5 100644
+--- a/kexec/arch/i386/crashdump-x86.c
++++ b/kexec/arch/i386/crashdump-x86.c
+@@ -102,35 +102,6 @@ static int get_kernel_paddr(struct kexec_info *UNUSED(info),
+ 	return -1;
+ }
+ 
+-/* Retrieve kernel symbol virtual address from /proc/kallsyms */
+-static unsigned long long get_kernel_sym(const char *symbol)
+-{
+-	const char *kallsyms = "/proc/kallsyms";
+-	char sym[128];
+-	char line[128];
+-	FILE *fp;
+-	unsigned long long vaddr;
+-	char type;
+-
+-	fp = fopen(kallsyms, "r");
+-	if (!fp) {
+-		fprintf(stderr, "Cannot open %s\n", kallsyms);
+-		return 0;
+-	}
+-
+-	while(fgets(line, sizeof(line), fp) != NULL) {
+-		if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3)
+-			continue;
+-		if (strcmp(sym, symbol) == 0) {
+-			dbgprintf("kernel symbol %s vaddr = %16llx\n", symbol, vaddr);
+-			return vaddr;
+-		}
+-	}
+-
+-	fprintf(stderr, "Cannot get kernel %s symbol address\n", symbol);
+-	return 0;
+-}
+-
+ /* Retrieve info regarding virtual address kernel has been compiled for and
+  * size of the kernel from /proc/kcore. Current /proc/kcore parsing from
+  * from kexec-tools fails because of malformed elf notes. A kernel patch has
+diff --git a/kexec/kexec.h b/kexec/kexec.h
+index 9194f1c..b4fafad 100644
+--- a/kexec/kexec.h
++++ b/kexec/kexec.h
+@@ -312,4 +312,6 @@ int xen_kexec_load(struct kexec_info *info);
+ int xen_kexec_unload(uint64_t kexec_flags);
+ void xen_kexec_exec(void);
+ 
++extern unsigned long long get_kernel_sym(const char *text);
++
+ #endif /* KEXEC_H */
+diff --git a/kexec/symbols.c b/kexec/symbols.c
+new file mode 100644
+index 0000000..ea6e327
+--- /dev/null
++++ b/kexec/symbols.c
+@@ -0,0 +1,41 @@
++#include <stdio.h>
++#include <string.h>
++#include "kexec.h"
++
++/* Retrieve kernel symbol virtual address from /proc/kallsyms */
++unsigned long long get_kernel_sym(const char *text)
++{
++	const char *kallsyms = "/proc/kallsyms";
++	char sym[128];
++	char line[128];
++	FILE *fp;
++	unsigned long long vaddr = 0;
++	char type;
++
++	fp = fopen(kallsyms, "r");
++	if (!fp) {
++		fprintf(stderr, "Cannot open %s\n", kallsyms);
++		return 0;
++	}
++
++	while (fgets(line, sizeof(line), fp) != NULL) {
++		unsigned long long addr;
++
++		if (sscanf(line, "%Lx %c %s", &addr, &type, sym) != 3)
++			continue;
++
++		if (strcmp(sym, text) == 0) {
++			dbgprintf("kernel symbol %s vaddr = %#llx\n",
++								text, addr);
++			vaddr = addr;
++			break;
++		}
++	}
++
++	fclose(fp);
++
++	if (vaddr == 0)
++		fprintf(stderr, "Cannot get kernel %s symbol address\n", text);
++
++	return vaddr;
++}
+-- 
+1.9.1
+
diff --git a/meta/recipes-kernel/kexec/kexec-tools/0003-arm64-identify-PHYS_OFFSET-correctly.patch b/meta/recipes-kernel/kexec/kexec-tools/0003-arm64-identify-PHYS_OFFSET-correctly.patch
new file mode 100644
index 0000000..285ce45
--- /dev/null
+++ b/meta/recipes-kernel/kexec/kexec-tools/0003-arm64-identify-PHYS_OFFSET-correctly.patch
@@ -0,0 +1,76 @@
+From 16df170ad4808d12acd5e919ac4f6e7f33a247b3 Mon Sep 17 00:00:00 2001
+From: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Date: Thu, 1 Sep 2016 10:57:42 +0900
+Subject: [PATCH 3/9] arm64: identify PHYS_OFFSET correctly
+
+Due to the kernel patch, commit e7cd190385d1 ("arm64: mark reserved
+memblock regions explicitly in iomem"), the current code will not be able
+to identify the correct value of PHYS_OFFSET if some "reserved" memory
+region, which is likely to be UEFI runtime services code/data, exists at
+an address below the first "System RAM" regions.
+
+This patch fixes this issue.
+
+Upstream-Status: Submitted [http://lists.infradead.org/pipermail/kexec/2016-November/017558.html]
+
+Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Signed-off-by: He Zhe <zhe.he at windriver.com>
+---
+ kexec/arch/arm64/iomem.h       |  7 +++++++
+ kexec/arch/arm64/kexec-arm64.c | 12 ++++++++++--
+ 2 files changed, 17 insertions(+), 2 deletions(-)
+ create mode 100644 kexec/arch/arm64/iomem.h
+
+diff --git a/kexec/arch/arm64/iomem.h b/kexec/arch/arm64/iomem.h
+new file mode 100644
+index 0000000..7fd66eb
+--- /dev/null
++++ b/kexec/arch/arm64/iomem.h
+@@ -0,0 +1,7 @@
++#ifndef IOMEM_H
++#define IOMEM_H
++
++#define SYSTEM_RAM		"System RAM\n"
++#define IOMEM_RESERVED		"reserved\n"
++
++#endif
+diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
+index 2e8839a..8ac811d 100644
+--- a/kexec/arch/arm64/kexec-arm64.c
++++ b/kexec/arch/arm64/kexec-arm64.c
+@@ -21,6 +21,7 @@
+ #include "crashdump-arm64.h"
+ #include "dt-ops.h"
+ #include "fs2dt.h"
++#include "iomem.h"
+ #include "kexec-syscall.h"
+ #include "arch/options.h"
+ 
+@@ -475,7 +476,14 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
+ 		return -1;
+ 
+ 	r = (struct memory_range *)data + nr;
+-	r->type = RANGE_RAM;
++
++	if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)))
++		r->type = RANGE_RAM;
++	else if (!strncmp(str, IOMEM_RESERVED, strlen(IOMEM_RESERVED)))
++		r->type = RANGE_RESERVED;
++	else
++		return 1;
++
+ 	r->start = base;
+ 	r->end = base + length - 1;
+ 
+@@ -494,7 +502,7 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
+ static int get_memory_ranges_iomem(struct memory_range *array,
+ 	unsigned int *count)
+ {
+-	*count = kexec_iomem_for_each_line("System RAM\n",
++	*count = kexec_iomem_for_each_line(NULL,
+ 		get_memory_ranges_iomem_cb, array);
+ 
+ 	if (!*count) {
+-- 
+1.9.1
+
diff --git a/meta/recipes-kernel/kexec/kexec-tools/0004-arm64-kdump-identify-memory-regions.patch b/meta/recipes-kernel/kexec/kexec-tools/0004-arm64-kdump-identify-memory-regions.patch
new file mode 100644
index 0000000..2fe4193
--- /dev/null
+++ b/meta/recipes-kernel/kexec/kexec-tools/0004-arm64-kdump-identify-memory-regions.patch
@@ -0,0 +1,202 @@
+From 48a4c7874d8264ddbfaec2e9858d7866a2d2eb60 Mon Sep 17 00:00:00 2001
+From: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Date: Wed, 5 Aug 2015 13:16:30 +0900
+Subject: [PATCH 4/9] arm64: kdump: identify memory regions
+
+The following regions need to be identified for later use:
+ a) memory regions which belong to the 1st kernel
+ b) usable memory reserved for crash dump kernel
+
+We go through /proc/iomem to find out a) and b) which are marked
+as "System RAM" and "Crash kernel", respectively.
+
+Upstream-Status: Submitted [http://lists.infradead.org/pipermail/kexec/2016-November/017559.html]
+
+Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Signed-off-by: He Zhe <zhe.he at windriver.com>
+---
+ kexec/arch/arm64/Makefile          |   2 +
+ kexec/arch/arm64/crashdump-arm64.c | 100 ++++++++++++++++++++++++++++++++++++-
+ kexec/arch/arm64/crashdump-arm64.h |  14 +++++-
+ kexec/arch/arm64/iomem.h           |   1 +
+ 4 files changed, 114 insertions(+), 3 deletions(-)
+
+diff --git a/kexec/arch/arm64/Makefile b/kexec/arch/arm64/Makefile
+index 74b677f..2d4ae0e 100644
+--- a/kexec/arch/arm64/Makefile
++++ b/kexec/arch/arm64/Makefile
+@@ -6,6 +6,8 @@ arm64_FS2DT_INCLUDE += \
+ 
+ arm64_DT_OPS += kexec/dt-ops.c
+ 
++arm64_MEM_REGIONS = kexec/mem_regions.c
++
+ arm64_CPPFLAGS += -I $(srcdir)/kexec/
+ 
+ arm64_KEXEC_SRCS += \
+diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c
+index d2272c8..dcaca43 100644
+--- a/kexec/arch/arm64/crashdump-arm64.c
++++ b/kexec/arch/arm64/crashdump-arm64.c
+@@ -1,5 +1,13 @@
+ /*
+  * ARM64 crashdump.
++ *     partly derived from arm implementation
++ *
++ * Copyright (c) 2014-2016 Linaro Limited
++ * Author: AKASHI Takahiro <takahiro.akashi at linaro.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
+  */
+ 
+ #define _GNU_SOURCE
+@@ -10,12 +18,102 @@
+ #include "kexec.h"
+ #include "crashdump.h"
+ #include "crashdump-arm64.h"
++#include "iomem.h"
+ #include "kexec-arm64.h"
+ #include "kexec-elf.h"
++#include "mem_regions.h"
+ 
+-struct memory_ranges usablemem_rgns = {};
++/* memory ranges on crashed kernel */
++static struct memory_range crash_memory_ranges[CRASH_MAX_MEMORY_RANGES];
++static struct memory_ranges crash_memory_rgns = {
++	.size = 0,
++	.max_size = CRASH_MAX_MEMORY_RANGES,
++	.ranges = crash_memory_ranges,
++};
++
++/* memory range reserved for crashkernel */
++struct memory_range crash_reserved_mem;
++struct memory_ranges usablemem_rgns = {
++	.size = 0,
++	.max_size = 1,
++	.ranges = &crash_reserved_mem,
++};
++
++/*
++ * iomem_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, respectively, crash_memory_ranges and crash_reserved_mem.
++ */
++
++static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr),
++				char *str, unsigned long long base,
++				unsigned long long length)
++{
++	if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0)
++		return mem_regions_add(&usablemem_rgns,
++				       base, length, RANGE_RAM);
++	else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0)
++		return mem_regions_add(&crash_memory_rgns,
++				       base, length, RANGE_RAM);
++
++	return 0;
++}
+ 
+ int is_crashkernel_mem_reserved(void)
+ {
++	if (!crash_reserved_mem.end)
++		kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
++
++	return crash_reserved_mem.start != crash_reserved_mem.end;
++}
++
++/*
++ * crash_get_memory_ranges() - read system physical memory
++ *
++ * Function reads through system physical memory and stores found memory
++ * regions in crash_memory_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.
++	 */
++	if (!usablemem_rgns.size)
++		kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
++
++	/* allow only a single region for crash dump kernel */
++	if (usablemem_rgns.size != 1) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	dbgprint_mem_range("Reserved memory range", &crash_reserved_mem, 1);
++
++	if (mem_regions_exclude(&crash_memory_rgns, &crash_reserved_mem)) {
++		fprintf(stderr,
++			"Error: Number of crash memory ranges excedeed the max limit\n");
++		errno = ENOMEM;
++		return -1;
++	}
++
++	/*
++	 * Make sure that the memory regions are sorted.
++	 */
++	mem_regions_sort(&crash_memory_rgns);
++
++	dbgprint_mem_range("Coredump memory ranges",
++			   crash_memory_rgns.ranges, crash_memory_rgns.size);
++
+ 	return 0;
+ }
+diff --git a/kexec/arch/arm64/crashdump-arm64.h b/kexec/arch/arm64/crashdump-arm64.h
+index f33c7a2..07a0ed0 100644
+--- a/kexec/arch/arm64/crashdump-arm64.h
++++ b/kexec/arch/arm64/crashdump-arm64.h
+@@ -1,12 +1,22 @@
+ /*
+  * ARM64 crashdump.
++ *
++ * Copyright (c) 2014-2016 Linaro Limited
++ * Author: AKASHI Takahiro <takahiro.akashi at linaro.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
+  */
+ 
+-#if !defined(CRASHDUMP_ARM64_H)
++#ifndef CRASHDUMP_ARM64_H
+ #define CRASHDUMP_ARM64_H
+ 
+ #include "kexec.h"
+ 
++#define CRASH_MAX_MEMORY_RANGES	32
++
+ extern struct memory_ranges usablemem_rgns;
++extern struct memory_range crash_reserved_mem;
+ 
+-#endif
++#endif /* CRASHDUMP_ARM64_H */
+diff --git a/kexec/arch/arm64/iomem.h b/kexec/arch/arm64/iomem.h
+index 7fd66eb..20cda87 100644
+--- a/kexec/arch/arm64/iomem.h
++++ b/kexec/arch/arm64/iomem.h
+@@ -2,6 +2,7 @@
+ #define IOMEM_H
+ 
+ #define SYSTEM_RAM		"System RAM\n"
++#define CRASH_KERNEL		"Crash kernel\n"
+ #define IOMEM_RESERVED		"reserved\n"
+ 
+ #endif
+-- 
+1.9.1
+
diff --git a/meta/recipes-kernel/kexec/kexec-tools/0005-arm64-kdump-add-elf-core-header-segment.patch b/meta/recipes-kernel/kexec/kexec-tools/0005-arm64-kdump-add-elf-core-header-segment.patch
new file mode 100644
index 0000000..fcdb167
--- /dev/null
+++ b/meta/recipes-kernel/kexec/kexec-tools/0005-arm64-kdump-add-elf-core-header-segment.patch
@@ -0,0 +1,191 @@
+From 769da25627cebb2a53caee5d5be78a32d376adc1 Mon Sep 17 00:00:00 2001
+From: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Date: Wed, 5 Aug 2015 13:45:15 +0900
+Subject: [PATCH 5/9] arm64: kdump: add elf core header segment
+
+Elf core header contains the information necessary for the coredump of
+the 1st kernel, including its physcal memory layout as well as cpu register
+states at the panic.
+The segment is allocated inside the reserved memory of crash dump kernel.
+
+Upstream-Status: Submitted [http://lists.infradead.org/pipermail/kexec/2016-November/017560.html]
+
+Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Signed-off-by: He Zhe <zhe.he at windriver.com>
+---
+ kexec/arch/arm64/crashdump-arm64.c | 96 ++++++++++++++++++++++++++++++++++++++
+ kexec/arch/arm64/crashdump-arm64.h |  3 ++
+ kexec/arch/arm64/iomem.h           |  2 +
+ kexec/arch/arm64/kexec-elf-arm64.c | 10 ++++
+ 4 files changed, 111 insertions(+)
+
+diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c
+index dcaca43..8346131 100644
+--- a/kexec/arch/arm64/crashdump-arm64.c
++++ b/kexec/arch/arm64/crashdump-arm64.c
+@@ -39,6 +39,39 @@ struct memory_ranges usablemem_rgns = {
+ 	.ranges = &crash_reserved_mem,
+ };
+ 
++struct memory_range elfcorehdr_mem;
++
++static struct crash_elf_info elf_info = {
++	.class		= ELFCLASS64,
++#if (__BYTE_ORDER == __LITTLE_ENDIAN)
++	.data		= ELFDATA2LSB,
++#else
++	.data		= ELFDATA2MSB,
++#endif
++	.machine	= EM_AARCH64,
++};
++
++/*
++ * Note: The returned value is correct only if !CONFIG_RANDOMIZE_BASE.
++ */
++static uint64_t get_kernel_page_offset(void)
++{
++	int i;
++
++	if (elf_info.kern_vaddr_start == UINT64_MAX)
++		return UINT64_MAX;
++
++	/* Current max virtual memory range is 48-bits. */
++	for (i = 48; i > 0; i--)
++		if (!(elf_info.kern_vaddr_start & (1UL << i)))
++			break;
++
++	if (i <= 0)
++		return UINT64_MAX;
++	else
++		return UINT64_MAX << i;
++}
++
+ /*
+  * iomem_range_callback() - callback called for each iomem region
+  * @data: not used
+@@ -62,6 +95,10 @@ static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr),
+ 	else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0)
+ 		return mem_regions_add(&crash_memory_rgns,
+ 				       base, length, RANGE_RAM);
++	else if (strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) == 0)
++		elf_info.kern_paddr_start = base;
++	else if (strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) == 0)
++		elf_info.kern_size = base + length - elf_info.kern_paddr_start;
+ 
+ 	return 0;
+ }
+@@ -115,5 +152,64 @@ static int crash_get_memory_ranges(void)
+ 	dbgprint_mem_range("Coredump memory ranges",
+ 			   crash_memory_rgns.ranges, crash_memory_rgns.size);
+ 
++	/*
++	 * For additional kernel code/data segment.
++	 * kern_paddr_start/kern_size are determined in iomem_range_callback
++	 */
++	elf_info.kern_vaddr_start = get_kernel_sym("_text");
++	if (!elf_info.kern_vaddr_start)
++		elf_info.kern_vaddr_start = UINT64_MAX;
++
++	return 0;
++}
++
++/*
++ * load_crashdump_segments() - load the elf core header
++ * @info: kexec info structure
++ *
++ * This function creates and loads an additional segment of elf core header
++ : which is used to construct /proc/vmcore on crash dump kernel.
++ *
++ * Return 0 in case of success and -1 in case of error.
++ */
++
++int load_crashdump_segments(struct kexec_info *info)
++{
++	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 crash dump kernel during panic.
++	 */
++
++	err = crash_get_memory_ranges();
++
++	if (err)
++		return err;
++
++	elf_info.page_offset = get_kernel_page_offset();
++	dbgprintf("%s: page_offset:   %016llx\n", __func__,
++			elf_info.page_offset);
++
++	err = crash_create_elf64_headers(info, &elf_info,
++			crash_memory_rgns.ranges, crash_memory_rgns.size,
++			&buf, &bufsz, ELF_CORE_HEADER_ALIGN);
++
++	if (err)
++		return err;
++
++	elfcorehdr = add_buffer_phys_virt(info, buf, bufsz, bufsz, 0,
++		crash_reserved_mem.start, crash_reserved_mem.end,
++		-1, 0);
++
++	elfcorehdr_mem.start = elfcorehdr;
++	elfcorehdr_mem.end = elfcorehdr + bufsz - 1;
++
++	dbgprintf("%s: elfcorehdr 0x%llx-0x%llx\n", __func__,
++			elfcorehdr_mem.start, elfcorehdr_mem.end);
++
+ 	return 0;
+ }
+diff --git a/kexec/arch/arm64/crashdump-arm64.h b/kexec/arch/arm64/crashdump-arm64.h
+index 07a0ed0..da75a2d 100644
+--- a/kexec/arch/arm64/crashdump-arm64.h
++++ b/kexec/arch/arm64/crashdump-arm64.h
+@@ -18,5 +18,8 @@
+ 
+ extern struct memory_ranges usablemem_rgns;
+ extern struct memory_range crash_reserved_mem;
++extern struct memory_range elfcorehdr_mem;
++
++extern int load_crashdump_segments(struct kexec_info *info);
+ 
+ #endif /* CRASHDUMP_ARM64_H */
+diff --git a/kexec/arch/arm64/iomem.h b/kexec/arch/arm64/iomem.h
+index 20cda87..d4864bb 100644
+--- a/kexec/arch/arm64/iomem.h
++++ b/kexec/arch/arm64/iomem.h
+@@ -2,6 +2,8 @@
+ #define IOMEM_H
+ 
+ #define SYSTEM_RAM		"System RAM\n"
++#define KERNEL_CODE		"Kernel code\n"
++#define KERNEL_DATA		"Kernel data\n"
+ #define CRASH_KERNEL		"Crash kernel\n"
+ #define IOMEM_RESERVED		"reserved\n"
+ 
+diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c
+index daf8bf0..c70a37a 100644
+--- a/kexec/arch/arm64/kexec-elf-arm64.c
++++ b/kexec/arch/arm64/kexec-elf-arm64.c
+@@ -119,6 +119,16 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf,
+ 	dbgprintf("%s: PE format:      %s\n", __func__,
+ 		(arm64_header_check_pe_sig(header) ? "yes" : "no"));
+ 
++	if (info->kexec_flags & KEXEC_ON_CRASH) {
++		/* create and initialize elf core header segment */
++		result = load_crashdump_segments(info);
++		if (result) {
++			dbgprintf("%s: Creating eflcorehdr failed.\n",
++								__func__);
++			goto exit;
++		}
++	}
++
+ 	/* load the kernel */
+ 	result = elf_exec_load(&ehdr, info);
+ 
+-- 
+1.9.1
+
diff --git a/meta/recipes-kernel/kexec/kexec-tools/0006-arm64-kdump-set-up-kernel-image-segment.patch b/meta/recipes-kernel/kexec/kexec-tools/0006-arm64-kdump-set-up-kernel-image-segment.patch
new file mode 100644
index 0000000..4443fd5
--- /dev/null
+++ b/meta/recipes-kernel/kexec/kexec-tools/0006-arm64-kdump-set-up-kernel-image-segment.patch
@@ -0,0 +1,137 @@
+From 4079c93ac5453ef5f7889ab64920c1e9427690ef Mon Sep 17 00:00:00 2001
+From: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Date: Tue, 17 Feb 2015 16:06:55 +0900
+Subject: [PATCH 6/9] arm64: kdump: set up kernel image segment
+
+On arm64, we can use the same kernel image as 1st kernel, but
+we have to modify the entry point as well as segments' addresses
+in the kernel's elf header in order to load them into correct places.
+
+Upstream-Status: Submitted [http://lists.infradead.org/pipermail/kexec/2016-November/017561.html]
+
+Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Signed-off-by: He Zhe <zhe.he at windriver.com>
+---
+ kexec/arch/arm64/crashdump-arm64.c | 23 +++++++++++++++++++++++
+ kexec/arch/arm64/crashdump-arm64.h |  1 +
+ kexec/arch/arm64/kexec-arm64.c     | 25 ++++++++++++++++++++-----
+ kexec/arch/arm64/kexec-elf-arm64.c | 10 +++++++++-
+ 4 files changed, 53 insertions(+), 6 deletions(-)
+
+diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c
+index 8346131..9517329 100644
+--- a/kexec/arch/arm64/crashdump-arm64.c
++++ b/kexec/arch/arm64/crashdump-arm64.c
+@@ -213,3 +213,26 @@ int load_crashdump_segments(struct kexec_info *info)
+ 
+ 	return 0;
+ }
++
++/*
++ * e_entry and p_paddr are actually in virtual address space.
++ * Those values will be translated to physcal addresses by
++ * using virt_to_phys().
++ * So let's get ready for later use so the memory base (phys_offset)
++ * will be correctly replaced with crash_reserved_mem.start.
++ */
++void modify_ehdr_for_crashdump(struct mem_ehdr *ehdr)
++{
++	struct mem_phdr *phdr;
++	int i;
++
++	ehdr->e_entry += - arm64_mem.phys_offset + crash_reserved_mem.start;
++
++	for (i = 0; i < ehdr->e_phnum; i++) {
++		phdr = &ehdr->e_phdr[i];
++		if (phdr->p_type != PT_LOAD)
++			continue;
++		phdr->p_paddr +=
++			(-arm64_mem.phys_offset + crash_reserved_mem.start);
++	}
++}
+diff --git a/kexec/arch/arm64/crashdump-arm64.h b/kexec/arch/arm64/crashdump-arm64.h
+index da75a2d..382f571 100644
+--- a/kexec/arch/arm64/crashdump-arm64.h
++++ b/kexec/arch/arm64/crashdump-arm64.h
+@@ -21,5 +21,6 @@ extern struct memory_range crash_reserved_mem;
+ extern struct memory_range elfcorehdr_mem;
+ 
+ extern int load_crashdump_segments(struct kexec_info *info);
++extern void modify_ehdr_for_crashdump(struct mem_ehdr *ehdr);
+ 
+ #endif /* CRASHDUMP_ARM64_H */
+diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
+index 8ac811d..cec4e41 100644
+--- a/kexec/arch/arm64/kexec-arm64.c
++++ b/kexec/arch/arm64/kexec-arm64.c
+@@ -307,12 +307,27 @@ unsigned long arm64_locate_kernel_segment(struct kexec_info *info)
+ {
+ 	unsigned long hole;
+ 
+-	hole = locate_hole(info,
+-		arm64_mem.text_offset + arm64_mem.image_size,
+-		MiB(2), 0, ULONG_MAX, 1);
++	if (info->kexec_flags & KEXEC_ON_CRASH) {
++		unsigned long hole_end;
++
++		hole = (crash_reserved_mem.start < mem_min ?
++				mem_min : crash_reserved_mem.start);
++		hole = _ALIGN_UP(hole, MiB(2));
++		hole_end = hole + arm64_mem.text_offset + arm64_mem.image_size;
++
++		if ((hole_end > mem_max) ||
++		    (hole_end > crash_reserved_mem.end)) {
++			dbgprintf("%s: Crash kernel out of range\n", __func__);
++			hole = ULONG_MAX;
++		}
++	} else {
++		hole = locate_hole(info,
++			arm64_mem.text_offset + arm64_mem.image_size,
++			MiB(2), 0, ULONG_MAX, 1);
+ 
+-	if (hole == ULONG_MAX)
+-		dbgprintf("%s: locate_hole failed\n", __func__);
++		if (hole == ULONG_MAX)
++			dbgprintf("%s: locate_hole failed\n", __func__);
++	}
+ 
+ 	return hole;
+ }
+diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c
+index c70a37a..842ce21 100644
+--- a/kexec/arch/arm64/kexec-elf-arm64.c
++++ b/kexec/arch/arm64/kexec-elf-arm64.c
+@@ -9,6 +9,7 @@
+ #include <stdlib.h>
+ #include <linux/elf.h>
+ 
++#include "crashdump-arm64.h"
+ #include "kexec-arm64.h"
+ #include "kexec-elf.h"
+ #include "kexec-syscall.h"
+@@ -105,7 +106,8 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf,
+ 	}
+ 
+ 	arm64_mem.vp_offset = _ALIGN_DOWN(ehdr.e_entry, MiB(2));
+-	arm64_mem.vp_offset -= kernel_segment - get_phys_offset();
++	if (!(info->kexec_flags & KEXEC_ON_CRASH))
++		arm64_mem.vp_offset -= kernel_segment - get_phys_offset();
+ 
+ 	dbgprintf("%s: kernel_segment: %016lx\n", __func__, kernel_segment);
+ 	dbgprintf("%s: text_offset:    %016lx\n", __func__,
+@@ -127,6 +129,12 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf,
+ 								__func__);
+ 			goto exit;
+ 		}
++
++		/*
++		 * offset addresses in order to fit vmlinux
++		 * (elf_exec) into crash kernel's memory
++		 */
++		modify_ehdr_for_crashdump(&ehdr);
+ 	}
+ 
+ 	/* load the kernel */
+-- 
+1.9.1
+
diff --git a/meta/recipes-kernel/kexec/kexec-tools/0007-arm64-kdump-set-up-other-segments.patch b/meta/recipes-kernel/kexec/kexec-tools/0007-arm64-kdump-set-up-other-segments.patch
new file mode 100644
index 0000000..1ee6809
--- /dev/null
+++ b/meta/recipes-kernel/kexec/kexec-tools/0007-arm64-kdump-set-up-other-segments.patch
@@ -0,0 +1,35 @@
+From 07ad14e12665221d754fde8e47c32ac18c24586a Mon Sep 17 00:00:00 2001
+From: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Date: Fri, 31 Jul 2015 20:01:39 +0900
+Subject: [PATCH 7/9] arm64: kdump: set up other segments
+
+We make sure that all the other segments, initrd and device-tree blob,
+also be loaded into the reserved memory of crash dump kernel.
+
+Upstream-Status: Submitted [http://lists.infradead.org/pipermail/kexec/2016-November/017562.html]
+
+Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Signed-off-by: He Zhe <zhe.he at windriver.com>
+---
+ kexec/arch/arm64/kexec-arm64.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
+index cec4e41..78a0035 100644
+--- a/kexec/arch/arm64/kexec-arm64.c
++++ b/kexec/arch/arm64/kexec-arm64.c
+@@ -374,7 +374,10 @@ int arm64_load_other_segments(struct kexec_info *info,
+ 	/* Put the other segments after the image. */
+ 
+ 	hole_min = image_base + arm64_mem.image_size;
+-	hole_max = ULONG_MAX;
++	if (info->kexec_flags & KEXEC_ON_CRASH)
++		hole_max = crash_reserved_mem.end;
++	else
++		hole_max = ULONG_MAX;
+ 
+ 	if (arm64_opts.initrd) {
+ 		initrd_buf = slurp_file(arm64_opts.initrd, &initrd_size);
+-- 
+1.9.1
+
diff --git a/meta/recipes-kernel/kexec/kexec-tools/0008-arm64-kdump-add-DT-properties-to-crash-dump-kernel-s.patch b/meta/recipes-kernel/kexec/kexec-tools/0008-arm64-kdump-add-DT-properties-to-crash-dump-kernel-s.patch
new file mode 100644
index 0000000..e8358c1
--- /dev/null
+++ b/meta/recipes-kernel/kexec/kexec-tools/0008-arm64-kdump-add-DT-properties-to-crash-dump-kernel-s.patch
@@ -0,0 +1,150 @@
+From 23bf7ac189cc3b87ceb9d1d3b69b5c4815354add Mon Sep 17 00:00:00 2001
+From: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Date: Wed, 27 Jan 2016 13:38:39 +0900
+Subject: [PATCH 8/9] arm64: kdump: add DT properties to crash dump kernel's
+ dtb
+
+We pass the following properties to crash dump kernel:
+linux,elfcorehdr: elf core header segment,
+		  same as "elfcorehdr=" kernel parameter on other archs
+linux,usable-memory-range: usable memory reserved for crash dump kernel
+
+Upstream-Status: Submitted [http://lists.infradead.org/pipermail/kexec/2016-November/017563.html]
+
+Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Signed-off-by: He Zhe <zhe.he at windriver.com>
+---
+ kexec/arch/arm64/kexec-arm64.c     | 76 +++++++++++++++++++++++++++++++++++---
+ kexec/arch/arm64/kexec-elf-arm64.c |  5 ---
+ 2 files changed, 71 insertions(+), 10 deletions(-)
+
+diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
+index 78a0035..a8fb64f 100644
+--- a/kexec/arch/arm64/kexec-arm64.c
++++ b/kexec/arch/arm64/kexec-arm64.c
+@@ -128,9 +128,6 @@ int arch_process_options(int argc, char **argv)
+ 		case OPT_INITRD:
+ 			arm64_opts.initrd = optarg;
+ 			break;
+-		case OPT_PANIC:
+-			die("load-panic (-p) not supported");
+-			break;
+ 		default:
+ 			break; /* Ignore core and unknown options. */
+ 		}
+@@ -285,8 +282,12 @@ on_success:
+  * setup_2nd_dtb - Setup the 2nd stage kernel's dtb.
+  */
+ 
+-static int setup_2nd_dtb(struct dtb *dtb, char *command_line)
++static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash)
+ {
++	char *new_buf;
++	int new_size;
++	int nodeoffset;
++	uint64_t range[2];
+ 	int result;
+ 
+ 	result = fdt_check_header(dtb->buf);
+@@ -298,8 +299,72 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line)
+ 
+ 	result = set_bootargs(dtb, command_line);
+ 
++	/* remove those anyway */
++	nodeoffset = fdt_path_offset(dtb->buf, "/chosen");
++	fdt_delprop(dtb->buf, nodeoffset, "linux,crashkernel-base");
++	fdt_delprop(dtb->buf, nodeoffset, "linux,crashkernel-size");
++
++	if (on_crash) {
++		nodeoffset = fdt_path_offset(dtb->buf, "/chosen");
++		fdt_delprop(dtb->buf, nodeoffset, "linux,elfcorehdr");
++		fdt_delprop(dtb->buf, nodeoffset, "linux,usable-memory-range");
++		new_size = fdt_totalsize(dtb->buf)
++			+ 2 * (sizeof(struct fdt_property)
++					+ FDT_TAGALIGN(sizeof(range)))
++			+ strlen("linux,elfcorehdr") + 1
++			+ strlen("linux,usable-memory-range") + 1;
++
++		new_buf = xmalloc(new_size);
++		result = fdt_open_into(dtb->buf, new_buf, new_size);
++		if (result) {
++			dbgprintf("%s: fdt_open_into failed: %s\n", __func__,
++				fdt_strerror(result));
++			result = -ENOSPC;
++			goto on_error;
++		}
++
++		range[0] = cpu_to_be64(elfcorehdr_mem.start);
++		range[1] = cpu_to_be64(elfcorehdr_mem.end
++				- elfcorehdr_mem.start + 1);
++		nodeoffset = fdt_path_offset(new_buf, "/chosen");
++		result = fdt_setprop(new_buf, nodeoffset, "linux,elfcorehdr",
++				(void *)range, sizeof(range));
++		if (result) {
++			dbgprintf("%s: fdt_setprop failed: %s\n", __func__,
++				fdt_strerror(result));
++			result = -EINVAL;
++			goto on_error;
++		}
++
++		range[0] = cpu_to_be64(crash_reserved_mem.start);
++		range[1] = cpu_to_be64(crash_reserved_mem.end
++				- crash_reserved_mem.start + 1);
++		nodeoffset = fdt_path_offset(new_buf, "/chosen");
++		result = fdt_setprop(new_buf, nodeoffset,
++				"linux,usable-memory-range",
++				(void *)range, sizeof(range));
++		if (result) {
++			dbgprintf("%s: fdt_setprop failed: %s\n", __func__,
++				fdt_strerror(result));
++			result = -EINVAL;
++			goto on_error;
++		}
++
++		fdt_pack(new_buf);
++		dtb->buf = new_buf;
++		dtb->size = fdt_totalsize(new_buf);
++	}
++
+ 	dump_reservemap(dtb);
+ 
++
++	return result;
++
++on_error:
++	fprintf(stderr, "kexec: %s failed.\n", __func__);
++	if (new_buf)
++		free(new_buf);
++
+ 	return result;
+ }
+ 
+@@ -366,7 +431,8 @@ int arm64_load_other_segments(struct kexec_info *info,
+ 		}
+ 	}
+ 
+-	result = setup_2nd_dtb(&dtb, command_line);
++	result = setup_2nd_dtb(&dtb, command_line,
++			info->kexec_flags & KEXEC_ON_CRASH);
+ 
+ 	if (result)
+ 		return -EFAILED;
+diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c
+index 842ce21..b17a31a 100644
+--- a/kexec/arch/arm64/kexec-elf-arm64.c
++++ b/kexec/arch/arm64/kexec-elf-arm64.c
+@@ -47,11 +47,6 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf,
+ 	int result;
+ 	int i;
+ 
+-	if (info->kexec_flags & KEXEC_ON_CRASH) {
+-		fprintf(stderr, "kexec: kdump not yet supported on arm64\n");
+-		return -EFAILED;
+-	}
+-
+ 	result = build_elf_exec_info(kernel_buf, kernel_size, &ehdr, 0);
+ 
+ 	if (result < 0) {
+-- 
+1.9.1
+
diff --git a/meta/recipes-kernel/kexec/kexec-tools/0009-arm64-kdump-Add-support-for-binary-image-files.patch b/meta/recipes-kernel/kexec/kexec-tools/0009-arm64-kdump-Add-support-for-binary-image-files.patch
new file mode 100644
index 0000000..6d42f83
--- /dev/null
+++ b/meta/recipes-kernel/kexec/kexec-tools/0009-arm64-kdump-Add-support-for-binary-image-files.patch
@@ -0,0 +1,52 @@
+From 5a4958f01a793c3e7f440f5bae75666a4349cc50 Mon Sep 17 00:00:00 2001
+From: Pratyush Anand <panand at redhat.com>
+Date: Thu, 14 May 2015 11:25:37 +0530
+Subject: [PATCH 9/9] arm64: kdump: Add support for binary image files
+
+This patch adds support to use binary image ie arch/arm64/boot/Image with
+kdump.
+
+Upstream-Status: Submitted [http://lists.infradead.org/pipermail/kexec/2016-November/017564.html]
+
+Signed-off-by: Pratyush Anand <panand at redhat.com>
+[takahiro.akashi at linaro.org: a bit reworked]
+Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
+Signed-off-by: He Zhe <zhe.he at windriver.com>
+---
+ kexec/arch/arm64/kexec-image-arm64.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/kexec/arch/arm64/kexec-image-arm64.c b/kexec/arch/arm64/kexec-image-arm64.c
+index 960ed96..982e431 100644
+--- a/kexec/arch/arm64/kexec-image-arm64.c
++++ b/kexec/arch/arm64/kexec-image-arm64.c
+@@ -4,7 +4,9 @@
+ 
+ #define _GNU_SOURCE
+ 
++#include "crashdump-arm64.h"
+ #include "kexec-arm64.h"
++#include "kexec-syscall.h"
+ #include <limits.h>
+ 
+ int image_arm64_probe(const char *kernel_buf, off_t kernel_size)
+@@ -58,6 +60,16 @@ int image_arm64_load(int argc, char **argv, const char *kernel_buf,
+ 	dbgprintf("%s: PE format:      %s\n", __func__,
+ 		(arm64_header_check_pe_sig(header) ? "yes" : "no"));
+ 
++	if (info->kexec_flags & KEXEC_ON_CRASH) {
++		/* create and initialize elf core header segment */
++		result = load_crashdump_segments(info);
++		if (result) {
++			dbgprintf("%s: Creating eflcorehdr failed.\n",
++								__func__);
++			goto exit;
++		}
++	}
++
+ 	/* load the kernel */
+ 	add_segment_phys_virt(info, kernel_buf, kernel_size,
+ 			kernel_segment + arm64_mem.text_offset,
+-- 
+1.9.1
+
diff --git a/meta/recipes-kernel/kexec/kexec-tools/kexec-aarch64.patch b/meta/recipes-kernel/kexec/kexec-tools/kexec-aarch64.patch
deleted file mode 100644
index b03f582..0000000
--- a/meta/recipes-kernel/kexec/kexec-tools/kexec-aarch64.patch
+++ /dev/null
@@ -1,801 +0,0 @@
-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
-
-Upstream-Status: Pending
-
-Signed-off-by: Kai Kang <kai.kang at windriver.com>
----
-
----
- configure.ac                            |    3 
- kexec/Makefile                          |    1 
- kexec/arch/arm64/Makefile               |   13 +
- kexec/arch/arm64/crashdump-arm64.c      |  305 ++++++++++++++++++++++++++++++++
- kexec/arch/arm64/include/arch/options.h |   26 ++
- kexec/arch/arm64/kexec-arm64.c          |  177 ++++++++++++++++++
- kexec/arch/arm64/kexec-arm64.h          |   20 ++
- kexec/arch/arm64/kexec-elf-arm64.c      |  114 +++++++++++
- kexec/kexec-syscall.h                   |    9 
- kexec/kexec.c                           |    2 
- purgatory/arch/arm64/Makefile           |    7 
- 11 files changed, 675 insertions(+), 2 deletions(-)
-
-Index: kexec-tools-2.0.10/configure.ac
-===================================================================
---- kexec-tools-2.0.10.orig/configure.ac
-+++ kexec-tools-2.0.10/configure.ac
-@@ -36,6 +36,9 @@ case $target_cpu in
- 		ARCH="ppc64"
- 		SUBARCH="LE"
- 		;;
-+	aarch64* )
-+		ARCH="arm64"
-+		;;
- 	arm* )
- 		ARCH="arm"
- 		;;
-Index: kexec-tools-2.0.10/kexec/Makefile
-===================================================================
---- kexec-tools-2.0.10.orig/kexec/Makefile
-+++ kexec-tools-2.0.10/kexec/Makefile
-@@ -71,6 +71,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/m68k/Makefile
-Index: kexec-tools-2.0.10/kexec/arch/arm64/Makefile
-===================================================================
---- /dev/null
-+++ kexec-tools-2.0.10/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.10/kexec/arch/arm64/crashdump-arm64.c
-===================================================================
---- /dev/null
-+++ kexec-tools-2.0.10/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.10/kexec/arch/arm64/include/arch/options.h
-===================================================================
---- /dev/null
-+++ kexec-tools-2.0.10/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.10/kexec/arch/arm64/kexec-arm64.c
-===================================================================
---- /dev/null
-+++ kexec-tools-2.0.10/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.10/kexec/arch/arm64/kexec-arm64.h
-===================================================================
---- /dev/null
-+++ kexec-tools-2.0.10/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.10/kexec/arch/arm64/kexec-elf-arm64.c
-===================================================================
---- /dev/null
-+++ kexec-tools-2.0.10/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.10/kexec/kexec-syscall.h
-===================================================================
---- kexec-tools-2.0.10.orig/kexec/kexec-syscall.h
-+++ kexec-tools-2.0.10/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
-@@ -108,6 +108,8 @@ static inline long kexec_file_load(int k
- #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)
-@@ -153,5 +155,8 @@ static inline long kexec_file_load(int k
- #ifdef __m68k__
- #define KEXEC_ARCH_NATIVE	KEXEC_ARCH_68K
- #endif
-+#if defined(__arm64__)
-+#define KEXEC_ARCH_NATIVE	KEXEC_ARCH_ARM64
-+#endif
- 
- #endif /* KEXEC_SYSCALL_H */
-Index: kexec-tools-2.0.10/kexec/kexec.c
-===================================================================
---- kexec-tools-2.0.10.orig/kexec/kexec.c
-+++ kexec-tools-2.0.10/kexec/kexec.c
-@@ -664,6 +664,8 @@ static int my_load(const char *type, int
- 	memset(&info, 0, sizeof(info));
- 	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.10/purgatory/arch/arm64/Makefile
-===================================================================
---- /dev/null
-+++ kexec-tools-2.0.10/purgatory/arch/arm64/Makefile
-@@ -0,0 +1,7 @@
-+#
-+# Purgatory arm64
-+#
-+
-+arm64_PURGATORY_SRCS =
-+
-+dist += purgatory/arch/arm64/Makefile $(arm64_PURGATORY_SRCS)
diff --git a/meta/recipes-kernel/kexec/kexec-tools/kexec-x32.patch b/meta/recipes-kernel/kexec/kexec-tools/kexec-x32.patch
deleted file mode 100644
index 26d18eb..0000000
--- a/meta/recipes-kernel/kexec/kexec-tools/kexec-x32.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-x86_64: Add support to build kexec-tools with x32 ABI
-
-Summary of changes,
-
-configure.ac: Add test for detect x32 ABI.
-purgatory/arch/x86_64/Makefile: Not use mcmodel large when
-	x32 ABI is set.
-kexec/arch/x86_64/kexec-elf-rel-x86_64.c: When x32 ABI is set
-	use ELFCLASS32 instead of ELFCLASS64.
-kexec/kexec-syscall.h: Add correct syscall number for x32 ABI.
-
-Upstream-Status: Submitted
-
-Signed-off-by: Aníbal Limón <anibal.limon at linux.intel.com>
-Signed-off-by: Mariano Lopez <mariano.lopez at linux.intel.com>
-
----
- configure.ac                             | 9 +++++++++
- kexec/arch/x86_64/kexec-elf-rel-x86_64.c | 4 ++++
- kexec/kexec-syscall.h                    | 4 ++++
- purgatory/arch/x86_64/Makefile           | 4 +++-
- 4 files changed, 20 insertions(+), 1 deletion(-)
-
-Index: kexec-tools-2.0.10/configure.ac
-===================================================================
---- kexec-tools-2.0.10.orig/configure.ac
-+++ kexec-tools-2.0.10/configure.ac
-@@ -56,6 +56,15 @@ case $target_cpu in
- 		;;
- 	ia64|x86_64|alpha|m68k )
- 		ARCH="$target_cpu"
-+
-+		dnl ---Test for x32 ABI in x86_64
-+		if test "x$ARCH" = "xx86_64" ; then
-+			AC_EGREP_CPP(x32_test,
-+			[#if defined(__x86_64__) && defined (__ILP32__)
-+				x32_test
-+			#endif
-+			], SUBARCH='x32', SUBARCH='64')
-+		fi
- 		;;
- 	* )
- 		AC_MSG_ERROR([unsupported architecture $target_cpu])
-Index: kexec-tools-2.0.10/kexec/arch/x86_64/kexec-elf-rel-x86_64.c
-===================================================================
---- kexec-tools-2.0.10.orig/kexec/arch/x86_64/kexec-elf-rel-x86_64.c
-+++ kexec-tools-2.0.10/kexec/arch/x86_64/kexec-elf-rel-x86_64.c
-@@ -8,7 +8,11 @@ int machine_verify_elf_rel(struct mem_eh
- 	if (ehdr->ei_data != ELFDATA2LSB) {
- 		return 0;
- 	}
-+#ifdef __ILP32__
-+	if (ehdr->ei_class != ELFCLASS32) {
-+#else
- 	if (ehdr->ei_class != ELFCLASS64) {
-+#endif
- 		return 0;
- 	}
- 	if (ehdr->e_machine != EM_X86_64) {
-Index: kexec-tools-2.0.10/kexec/kexec-syscall.h
-===================================================================
---- kexec-tools-2.0.10.orig/kexec/kexec-syscall.h
-+++ kexec-tools-2.0.10/kexec/kexec-syscall.h
-@@ -31,8 +31,12 @@
- #define __NR_kexec_load		268
- #endif
- #ifdef __x86_64__
-+#ifdef __ILP32__
-+#define __NR_kexec_load		528
-+#else
- #define __NR_kexec_load		246
- #endif
-+#endif
- #ifdef __s390x__
- #define __NR_kexec_load		277
- #endif
-Index: kexec-tools-2.0.10/purgatory/arch/x86_64/Makefile
-===================================================================
---- kexec-tools-2.0.10.orig/purgatory/arch/x86_64/Makefile
-+++ kexec-tools-2.0.10/purgatory/arch/x86_64/Makefile
-@@ -23,4 +23,6 @@ x86_64_PURGATORY_SRCS += purgatory/arch/
- x86_64_PURGATORY_SRCS += purgatory/arch/i386/vga.c
- x86_64_PURGATORY_SRCS += purgatory/arch/i386/pic.c
- 
--x86_64_PURGATORY_EXTRA_CFLAGS = -mcmodel=large
-+ifeq ($(SUBARCH),64)
-+        x86_64_PURGATORY_EXTRA_CFLAGS = -mcmodel=large
-+endif
diff --git a/meta/recipes-kernel/kexec/kexec-tools_2.0.12.bb b/meta/recipes-kernel/kexec/kexec-tools_2.0.14.bb
similarity index 55%
rename from meta/recipes-kernel/kexec/kexec-tools_2.0.12.bb
rename to meta/recipes-kernel/kexec/kexec-tools_2.0.14.bb
index 59376c8..de5ce44 100644
--- a/meta/recipes-kernel/kexec/kexec-tools_2.0.12.bb
+++ b/meta/recipes-kernel/kexec/kexec-tools_2.0.14.bb
@@ -3,15 +3,22 @@ export LDFLAGS = "-L${STAGING_LIBDIR}"
 EXTRA_OECONF = " --with-zlib=yes"
 
 SRC_URI += " \
-            file://kexec-aarch64.patch \
-            file://kexec-x32.patch \
             file://0002-powerpc-change-the-memory-size-limit.patch \
             file://0001-purgatory-Pass-r-directly-to-linker.patch \
             file://0001-vmcore-dmesg-Define-_GNU_SOURCE.patch \
+            file://0001-kexec-exntend-the-semantics-of-kexec_iomem_for_each_.patch \
+            file://0002-kexec-generalize-and-rename-get_kernel_stext_sym.patch \
+            file://0003-arm64-identify-PHYS_OFFSET-correctly.patch \
+            file://0004-arm64-kdump-identify-memory-regions.patch \
+            file://0005-arm64-kdump-add-elf-core-header-segment.patch \
+            file://0006-arm64-kdump-set-up-kernel-image-segment.patch \
+            file://0007-arm64-kdump-set-up-other-segments.patch \
+            file://0008-arm64-kdump-add-DT-properties-to-crash-dump-kernel-s.patch \
+            file://0009-arm64-kdump-Add-support-for-binary-image-files.patch \
          "
 
-SRC_URI[md5sum] = "10ddaae0e86af54407b164a1f5a39cc3"
-SRC_URI[sha256sum] = "cc7b60dad0da202004048a6179d8a53606943062dd627a2edba45a8ea3a85135"
+SRC_URI[md5sum] = "b2b2c5e6b29d467d6e99d587fb6b7cf5"
+SRC_URI[sha256sum] = "b3e69519d2acced256843b1e8f1ecfa00d9b54fa07449ed78f05b9193f239370"
 
 PACKAGES =+ "kexec kdump vmcore-dmesg"
 
-- 
2.8.3




More information about the Openembedded-core mailing list