summaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/kexec
diff options
context:
space:
mode:
authorKai Kang <kai.kang@windriver.com>2014-12-18 16:51:10 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-12-23 10:18:18 +0000
commit8bf791c790ab552f207f3de324c683ed155cc3bf (patch)
treece5ade185ea1b4e8ef1bfde3660120e3b659ef2f /meta/recipes-kernel/kexec
parentf78f9d7adb25d1c422b6e6f3371f1092c16157e3 (diff)
downloadpoky-8bf791c790ab552f207f3de324c683ed155cc3bf.tar.gz
kexec-tools: add aarch64 support
Add patch from https://fedorapeople.org/~hrw/aarch64/for-fedora/kexec-aarch64.patch to add aarch64 support for kexec-tools. (From OE-Core rev: 342ef3196bd754866bbdb54d538804ab71926553) Signed-off-by: Kai Kang <kai.kang@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-kernel/kexec')
-rw-r--r--meta/recipes-kernel/kexec/kexec-tools.inc2
-rw-r--r--meta/recipes-kernel/kexec/kexec-tools/kexec-aarch64.patch801
-rw-r--r--meta/recipes-kernel/kexec/kexec-tools_2.0.8.bb4
3 files changed, 805 insertions, 2 deletions
diff --git a/meta/recipes-kernel/kexec/kexec-tools.inc b/meta/recipes-kernel/kexec/kexec-tools.inc
index 7e3b7adfc7..312424a88f 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
12 12
13inherit autotools-brokensep 13inherit autotools-brokensep
14 14
15COMPATIBLE_HOST = '(x86_64.*|i.86.*|arm.*|powerpc.*|mips.*)-(linux|freebsd.*)' 15COMPATIBLE_HOST = '(x86_64.*|i.86.*|arm.*|aarch64.*|powerpc.*|mips.*)-(linux|freebsd.*)'
16 16
17INSANE_SKIP_${PN} = "arch" 17INSANE_SKIP_${PN} = "arch"
18 18
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 0000000000..b697a54b90
--- /dev/null
+++ b/meta/recipes-kernel/kexec/kexec-tools/kexec-aarch64.patch
@@ -0,0 +1,801 @@
1From: Geoff Levand <geoff@infradead.org>
2Date: Mon, 15 Jul 2013 23:32:36 +0000 (-0700)
3Subject: Add arm64 support
4X-Git-Url: https://git.linaro.org/gitweb?p=people%2Fgeoff%2Fkexec-tools.git;a=commitdiff_plain;h=fbf5ac6c2c70ec0f6da2b9ff563e573999752c01
5
6Add arm64 support
7
8Signed-off-by: Geoff Levand <geoff@infradead.org>
9
10Get patch from:
11https://fedorapeople.org/~hrw/aarch64/for-fedora/kexec-aarch64.patch
12
13Upstream-Status: Pending
14
15Signed-off-by: Kai Kang <kai.kang@windriver.com>
16---
17
18Index: kexec-tools-2.0.4/configure.ac
19===================================================================
20--- kexec-tools-2.0.4.orig/configure.ac
21+++ kexec-tools-2.0.4/configure.ac
22@@ -30,6 +30,9 @@ case $target_cpu in
23 powerpc64 )
24 ARCH="ppc64"
25 ;;
26+ aarch64 )
27+ ARCH="arm64"
28+ ;;
29 arm* )
30 ARCH="arm"
31 ;;
32Index: kexec-tools-2.0.4/kexec/Makefile
33===================================================================
34--- kexec-tools-2.0.4.orig/kexec/Makefile
35+++ kexec-tools-2.0.4/kexec/Makefile
36@@ -70,6 +70,7 @@ KEXEC_SRCS += $($(ARCH)_FS2DT)
37
38 include $(srcdir)/kexec/arch/alpha/Makefile
39 include $(srcdir)/kexec/arch/arm/Makefile
40+include $(srcdir)/kexec/arch/arm64/Makefile
41 include $(srcdir)/kexec/arch/i386/Makefile
42 include $(srcdir)/kexec/arch/ia64/Makefile
43 include $(srcdir)/kexec/arch/mips/Makefile
44Index: kexec-tools-2.0.4/kexec/arch/arm64/Makefile
45===================================================================
46--- /dev/null
47+++ kexec-tools-2.0.4/kexec/arch/arm64/Makefile
48@@ -0,0 +1,13 @@
49+
50+arm64_KEXEC_SRCS += \
51+ kexec/arch/arm64/kexec-arm64.c \
52+ kexec/arch/arm64/kexec-elf-arm64.c \
53+ kexec/arch/arm64/crashdump-arm64.c
54+
55+arm64_ARCH_REUSE_INITRD =
56+arm64_ADD_SEGMENT =
57+arm64_VIRT_TO_PHYS =
58+
59+dist += $(arm64_KEXEC_SRCS) \
60+ kexec/arch/arm64/Makefile \
61+ kexec/arch/arm64/kexec-arm64.h
62Index: kexec-tools-2.0.4/kexec/arch/arm64/crashdump-arm64.c
63===================================================================
64--- /dev/null
65+++ kexec-tools-2.0.4/kexec/arch/arm64/crashdump-arm64.c
66@@ -0,0 +1,305 @@
67+/*
68+ * This program is free software; you can redistribute it and/or modify
69+ * it under the terms of the GNU General Public License as published by
70+ * the Free Software Foundation (version 2 of the License).
71+ */
72+
73+#include "../../kexec.h"
74+#include "../../kexec-elf.h"
75+#include "../../crashdump.h"
76+
77+int is_crashkernel_mem_reserved(void)
78+{
79+ return 0;
80+}
81+
82+#if 0
83+/*
84+ * Used to save various memory ranges/regions needed for the captured
85+ * kernel to boot. (lime memmap= option in other archs)
86+ */
87+static struct memory_range crash_memory_ranges[CRASH_MAX_MEMORY_RANGES];
88+struct memory_ranges usablemem_rgns = {
89+ .size = 0,
90+ .ranges = crash_memory_ranges,
91+};
92+
93+/* memory range reserved for crashkernel */
94+static struct memory_range crash_reserved_mem;
95+
96+static struct crash_elf_info elf_info = {
97+ .class = ELFCLASS32,
98+ .data = ELFDATA2LSB,
99+ .machine = EM_ARM,
100+ .page_offset = PAGE_OFFSET,
101+};
102+
103+unsigned long phys_offset;
104+
105+/**
106+ * crash_range_callback() - callback called for each iomem region
107+ * @data: not used
108+ * @nr: not used
109+ * @str: name of the memory region
110+ * @base: start address of the memory region
111+ * @length: size of the memory region
112+ *
113+ * This function is called once for each memory region found in /proc/iomem. It
114+ * locates system RAM and crashkernel reserved memory and places these to
115+ * variables: @crash_memory_ranges and @crash_reserved_mem. Number of memory
116+ * regions is placed in @crash_memory_nr_ranges.
117+ */
118+static int crash_range_callback(void *UNUSED(data), int UNUSED(nr),
119+ char *str, unsigned long base,
120+ unsigned long length)
121+{
122+ struct memory_range *range;
123+
124+ if (usablemem_rgns.size >= CRASH_MAX_MEMORY_RANGES)
125+ return 1;
126+
127+ range = usablemem_rgns.ranges + usablemem_rgns.size;
128+
129+ if (strncmp(str, "System RAM\n", 11) == 0) {
130+ range->start = base;
131+ range->end = base + length - 1;
132+ range->type = RANGE_RAM;
133+ usablemem_rgns.size++;
134+ } else if (strncmp(str, "Crash kernel\n", 13) == 0) {
135+ crash_reserved_mem.start = base;
136+ crash_reserved_mem.end = base + length - 1;
137+ crash_reserved_mem.type = RANGE_RAM;
138+ }
139+
140+ return 0;
141+}
142+
143+/**
144+ * crash_exclude_range() - excludes memory region reserved for crashkernel
145+ *
146+ * Function locates where crashkernel reserved memory is and removes that region
147+ * from the available memory regions.
148+ */
149+static void crash_exclude_range(void)
150+{
151+ const struct memory_range *range = &crash_reserved_mem;
152+ int i;
153+
154+ for (i = 0; i < usablemem_rgns.size; i++) {
155+ struct memory_range *r = usablemem_rgns.ranges + i;
156+
157+ /*
158+ * We assume that crash area is fully contained in
159+ * some larger memory area.
160+ */
161+ if (r->start <= range->start && r->end >= range->end) {
162+ struct memory_range *new;
163+ /*
164+ * Let's split this area into 2 smaller ones and
165+ * remove excluded range from between. First create
166+ * new entry for the remaining area.
167+ */
168+ new = usablemem_rgns.ranges + usablemem_rgns.size;
169+ new->start = range->end + 1;
170+ new->end = r->end;
171+ usablemem_rgns.size++;
172+ /*
173+ * Next update this area to end before excluded range.
174+ */
175+ r->end = range->start - 1;
176+ break;
177+ }
178+ }
179+}
180+
181+static int range_cmp(const void *a1, const void *a2)
182+{
183+ const struct memory_range *r1 = a1;
184+ const struct memory_range *r2 = a2;
185+
186+ if (r1->start > r2->start)
187+ return 1;
188+ if (r1->start < r2->start)
189+ return -1;
190+
191+ return 0;
192+}
193+
194+/**
195+ * crash_get_memory_ranges() - read system physical memory
196+ *
197+ * Function reads through system physical memory and stores found memory regions
198+ * in @crash_memory_ranges. Number of memory regions found is placed in
199+ * @crash_memory_nr_ranges. Regions are sorted in ascending order.
200+ *
201+ * Returns %0 in case of success and %-1 otherwise (errno is set).
202+ */
203+static int crash_get_memory_ranges(void)
204+{
205+ /*
206+ * First read all memory regions that can be considered as
207+ * system memory including the crash area.
208+ */
209+ kexec_iomem_for_each_line(NULL, crash_range_callback, NULL);
210+
211+ if (usablemem_rgns.size < 1) {
212+ errno = EINVAL;
213+ return -1;
214+ }
215+
216+ /*
217+ * Exclude memory reserved for crashkernel (this may result a split memory
218+ * region).
219+ */
220+ crash_exclude_range();
221+
222+ /*
223+ * Make sure that the memory regions are sorted.
224+ */
225+ qsort(usablemem_rgns.ranges, usablemem_rgns.size,
226+ sizeof(*usablemem_rgns.ranges), range_cmp);
227+
228+ return 0;
229+}
230+
231+/**
232+ * cmdline_add_elfcorehdr() - adds elfcorehdr= to @cmdline
233+ * @cmdline: buffer where parameter is placed
234+ * @elfcorehdr: physical address of elfcorehdr
235+ *
236+ * Function appends 'elfcorehdr=start' at the end of the command line given in
237+ * @cmdline. Note that @cmdline must be at least %COMMAND_LINE_SIZE bytes long
238+ * (inclunding %NUL).
239+ */
240+static void cmdline_add_elfcorehdr(char *cmdline, unsigned long elfcorehdr)
241+{
242+ char buf[COMMAND_LINE_SIZE];
243+ int buflen;
244+
245+ buflen = snprintf(buf, sizeof(buf), "%s elfcorehdr=%#lx",
246+ cmdline, elfcorehdr);
247+ if (buflen < 0)
248+ die("Failed to construct elfcorehdr= command line parameter\n");
249+ if (buflen >= sizeof(buf))
250+ die("Command line overflow\n");
251+
252+ (void) strncpy(cmdline, buf, COMMAND_LINE_SIZE);
253+ cmdline[COMMAND_LINE_SIZE - 1] = '\0';
254+}
255+
256+/**
257+ * cmdline_add_mem() - adds mem= parameter to kernel command line
258+ * @cmdline: buffer where parameter is placed
259+ * @size: size of the kernel reserved memory (in bytes)
260+ *
261+ * This function appends 'mem=size' at the end of the command line given in
262+ * @cmdline. Note that @cmdline must be at least %COMMAND_LINE_SIZE bytes long
263+ * (including %NUL).
264+ */
265+static void cmdline_add_mem(char *cmdline, unsigned long size)
266+{
267+ char buf[COMMAND_LINE_SIZE];
268+ int buflen;
269+
270+ buflen = snprintf(buf, sizeof(buf), "%s mem=%ldK", cmdline, size >> 10);
271+ if (buflen < 0)
272+ die("Failed to construct mem= command line parameter\n");
273+ if (buflen >= sizeof(buf))
274+ die("Command line overflow\n");
275+
276+ (void) strncpy(cmdline, buf, COMMAND_LINE_SIZE);
277+ cmdline[COMMAND_LINE_SIZE - 1] = '\0';
278+}
279+
280+static unsigned long long range_size(const struct memory_range *r)
281+{
282+ return r->end - r->start + 1;
283+}
284+
285+static void dump_memory_ranges(void)
286+{
287+ int i;
288+
289+ if (!kexec_debug)
290+ return;
291+
292+ dbgprintf("crashkernel: [%#llx - %#llx] (%ldM)\n",
293+ crash_reserved_mem.start, crash_reserved_mem.end,
294+ (unsigned long)range_size(&crash_reserved_mem) >> 20);
295+
296+ for (i = 0; i < usablemem_rgns.size; i++) {
297+ struct memory_range *r = usablemem_rgns.ranges + i;
298+ dbgprintf("memory range: [%#llx - %#llx] (%ldM)\n",
299+ r->start, r->end, (unsigned long)range_size(r) >> 20);
300+ }
301+}
302+
303+/**
304+ * load_crashdump_segments() - loads additional segments needed for kdump
305+ * @info: kexec info structure
306+ * @mod_cmdline: kernel command line
307+ *
308+ * This function loads additional segments which are needed for the dump capture
309+ * kernel. It also updates kernel command line passed in @mod_cmdline to have
310+ * right parameters for the dump capture kernel.
311+ *
312+ * Return %0 in case of success and %-1 in case of error.
313+ */
314+int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline)
315+{
316+ unsigned long elfcorehdr;
317+ unsigned long bufsz;
318+ void *buf;
319+ int err;
320+
321+ /*
322+ * First fetch all the memory (RAM) ranges that we are going to pass to
323+ * the crashdump kernel during panic.
324+ */
325+ err = crash_get_memory_ranges();
326+ if (err)
327+ return err;
328+
329+ /*
330+ * Now that we have memory regions sorted, we can use first memory
331+ * region as PHYS_OFFSET.
332+ */
333+ phys_offset = usablemem_rgns.ranges->start;
334+ dbgprintf("phys_offset: %#lx\n", phys_offset);
335+
336+ err = crash_create_elf32_headers(info, &elf_info,
337+ usablemem_rgns.ranges,
338+ usablemem_rgns.size, &buf, &bufsz,
339+ ELF_CORE_HEADER_ALIGN);
340+ if (err)
341+ return err;
342+
343+ /*
344+ * We allocate ELF core header from the end of the memory area reserved
345+ * for the crashkernel. We align the header to SECTION_SIZE (which is
346+ * 1MB) so that available memory passed in kernel command line will be
347+ * aligned to 1MB. This is because kernel create_mapping() wants memory
348+ * regions to be aligned to SECTION_SIZE.
349+ */
350+ elfcorehdr = add_buffer_phys_virt(info, buf, bufsz, bufsz, 1 << 20,
351+ crash_reserved_mem.start,
352+ crash_reserved_mem.end, -1, 0);
353+
354+ dbgprintf("elfcorehdr: %#lx\n", elfcorehdr);
355+ cmdline_add_elfcorehdr(mod_cmdline, elfcorehdr);
356+
357+ /*
358+ * Add 'mem=size' parameter to dump capture kernel command line. This
359+ * prevents the dump capture kernel from using any other memory regions
360+ * which belong to the primary kernel.
361+ */
362+ cmdline_add_mem(mod_cmdline, elfcorehdr - crash_reserved_mem.start);
363+
364+ dump_memory_ranges();
365+ dbgprintf("kernel command line: \"%s\"\n", mod_cmdline);
366+
367+ return 0;
368+}
369+
370+#endif
371+
372Index: kexec-tools-2.0.4/kexec/arch/arm64/include/arch/options.h
373===================================================================
374--- /dev/null
375+++ kexec-tools-2.0.4/kexec/arch/arm64/include/arch/options.h
376@@ -0,0 +1,26 @@
377+#ifndef KEXEC_ARCH_ARM64_OPTIONS_H
378+#define KEXEC_ARCH_ARM64_OPTIONS_H
379+
380+//#define OPT_ARCH_MAX ((OPT_MAX)+0)
381+
382+#define OPT_APPEND ((OPT_MAX)+0)
383+#define OPT_RAMDISK ((OPT_MAX)+1)
384+#define OPT_DTB ((OPT_MAX)+2)
385+
386+#define OPT_ARCH_MAX ((OPT_MAX)+3)
387+
388+
389+#define KEXEC_ARCH_OPTIONS \
390+ KEXEC_OPTIONS \
391+ { "append", 1, NULL, OPT_APPEND }, \
392+ { "command-line", 1, NULL, OPT_APPEND }, \
393+ { "dtb", 1, NULL, OPT_DTB }, \
394+ { "initrd", 1, NULL, OPT_RAMDISK }, \
395+ { "ramdisk", 1, NULL, OPT_RAMDISK }, \
396+
397+#define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR /* Only accept long arch options. */
398+
399+#define KEXEC_ALL_OPTIONS KEXEC_ARCH_OPTIONS
400+#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR
401+
402+#endif /* KEXEC_ARCH_ARM64_OPTIONS_H */
403Index: kexec-tools-2.0.4/kexec/arch/arm64/kexec-arm64.c
404===================================================================
405--- /dev/null
406+++ kexec-tools-2.0.4/kexec/arch/arm64/kexec-arm64.c
407@@ -0,0 +1,177 @@
408+/*
409+ * ARM64 kexec support.
410+ */
411+
412+#define _GNU_SOURCE
413+
414+#include <errno.h>
415+#include <stddef.h>
416+
417+//#include <linux/kexec.h>
418+
419+#include "../../kexec.h"
420+#include "../../kexec-syscall.h"
421+#include "kexec-arm64.h"
422+
423+
424+void arch_usage(void)
425+{
426+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
427+
428+ printf(
429+" --append=STRING Set the kernel command line to STRING.\n"
430+" --command-line=STRING Set the kernel command line to STRING.\n"
431+" --dtb=FILE Use FILE as the device tree blob.\n"
432+" --initrd=FILE Use FILE as the kernel initial ramdisk.\n"
433+" --ramdisk=FILE Use FILE as the kernel initial ramdisk.\n");
434+
435+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
436+}
437+
438+int arch_process_options(int UNUSED(argc), char **UNUSED(argv))
439+{
440+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
441+ return 0;
442+}
443+
444+const struct arch_map_entry arches[] = {
445+ { "aarch64", KEXEC_ARCH_ARM64 },
446+ { NULL, 0 },
447+};
448+
449+void arch_update_purgatory(struct kexec_info *UNUSED(info))
450+{
451+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
452+}
453+
454+unsigned long virt_to_phys(unsigned long addr)
455+{
456+ fprintf(stderr, "%s:%d: %016lx -> %016lx\n", __func__, __LINE__, addr,
457+ addr + 0x080000000UL);
458+ return addr + 0x080000000UL;
459+}
460+
461+void add_segment(struct kexec_info *info, const void *buf, size_t bufsz,
462+ unsigned long base, size_t memsz)
463+{
464+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
465+ add_segment_phys_virt(info, buf, bufsz, base, memsz, 1);
466+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
467+}
468+
469+static int get_memory_ranges_1(struct memory_range **range, int *ranges,
470+ unsigned long kexec_flags)
471+{
472+ static struct memory_range memory_range[KEXEC_SEGMENT_MAX];
473+ const char *iomem;
474+ int range_count = 0;
475+ char line[MAX_LINE];
476+ FILE *fp;
477+
478+ iomem = proc_iomem();
479+ fp = fopen(iomem, "r");
480+
481+ if (!fp) {
482+ fprintf(stderr, "Cannot open %s: %s\n",
483+ iomem, strerror(errno));
484+ return -1;
485+ }
486+
487+ dbgprintf("memory ranges:\n");
488+
489+ while(fgets(line, sizeof(line), fp) != 0) {
490+ struct memory_range r;
491+ char *str;
492+ int consumed;
493+
494+ if (range_count >= KEXEC_SEGMENT_MAX)
495+ break;
496+
497+ if (sscanf(line, "%Lx-%Lx : %n", &r.start, &r.end, &consumed)
498+ != 2)
499+ continue;
500+
501+ str = line + consumed;
502+ r.end++;
503+
504+ if (memcmp(str, "System RAM\n", 11)) {
505+ dbgprintf(" Skip: %016Lx - %016Lx : %s", r.start, r.end,
506+ str);
507+ continue;
508+ }
509+
510+ r.type = RANGE_RAM;
511+ memory_range[range_count] = r;
512+ range_count++;
513+
514+ dbgprintf(" Add: %016Lx - %016Lx : %s", r.start, r.end, str);
515+ }
516+
517+ fclose(fp);
518+ *range = memory_range;
519+ *ranges = range_count;
520+
521+ return 0;
522+}
523+
524+static int get_memory_ranges_2(struct memory_range **range, int *ranges,
525+ unsigned long UNUSED(kexec_flags))
526+{
527+ static struct memory_range memory_range[2];
528+
529+ memory_range[0].start = 0x080000000;
530+ memory_range[0].end = 0x100000000;
531+ memory_range[0].type = RANGE_RAM;
532+
533+ memory_range[1].start = 0x900000000;
534+ memory_range[1].end = 0x880000000;
535+ memory_range[1].type = RANGE_RAM;
536+
537+ *range = memory_range;
538+ *ranges = sizeof(memory_range) / sizeof(memory_range[0]);
539+
540+ return 0;
541+}
542+
543+int get_memory_ranges(struct memory_range **range, int *ranges,
544+ unsigned long kexec_flags)
545+{
546+ /* FIXME: Should get this info from device tree. */
547+
548+ return get_memory_ranges_1(range, ranges, kexec_flags);
549+}
550+
551+struct file_type file_type[] = {
552+ { "elf-arm64", elf_arm64_probe, elf_arm64_load, elf_arm64_usage },
553+};
554+
555+int file_types = sizeof(file_type) / sizeof(file_type[0]);
556+
557+int arch_compat_trampoline(struct kexec_info *info)
558+{
559+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
560+ return 0;
561+}
562+
563+void arch_reuse_initrd(void)
564+{
565+}
566+
567+int machine_verify_elf_rel(struct mem_ehdr *ehdr)
568+{
569+ (void)ehdr;
570+
571+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
572+ return 0;
573+}
574+
575+void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type,
576+ void *location, unsigned long address, unsigned long value)
577+{
578+ (void)ehdr;
579+ (void)r_type;
580+ (void)location;
581+ (void)address;
582+ (void)value;
583+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
584+}
585Index: kexec-tools-2.0.4/kexec/arch/arm64/kexec-arm64.h
586===================================================================
587--- /dev/null
588+++ kexec-tools-2.0.4/kexec/arch/arm64/kexec-arm64.h
589@@ -0,0 +1,20 @@
590+/*
591+ * ARM64 kexec support.
592+ */
593+
594+#if !defined(KEXEC_ARM64_H)
595+#define KEXEC_ARM64_H
596+
597+/* #include <linux/kexec.h> FIXME: this is broken */
598+#include <sys/types.h>
599+
600+#include "../../kexec.h"
601+
602+#define KEXEC_SEGMENT_MAX 16 /* FIXME: this should come from <linux/kexec.h> */
603+
604+int elf_arm64_probe(const char *buf, off_t len);
605+int elf_arm64_load(int argc, char **argv, const char *buf, off_t len,
606+ struct kexec_info *info);
607+void elf_arm64_usage(void);
608+
609+#endif
610\ No newline at end of file
611Index: kexec-tools-2.0.4/kexec/arch/arm64/kexec-elf-arm64.c
612===================================================================
613--- /dev/null
614+++ kexec-tools-2.0.4/kexec/arch/arm64/kexec-elf-arm64.c
615@@ -0,0 +1,114 @@
616+/*
617+ * ARM64 kexec support.
618+ */
619+
620+#define _GNU_SOURCE
621+
622+#include <elf.h>
623+#include <getopt.h>
624+
625+#include "../../kexec-syscall.h"
626+
627+#include "kexec-arm64.h"
628+#include "arch/options.h"
629+
630+#if !defined(EM_AARCH64)
631+# define EM_AARCH64 183
632+#endif
633+
634+int elf_arm64_probe(const char *buf, off_t len)
635+{
636+ int result;
637+ struct mem_ehdr ehdr;
638+
639+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
640+
641+ result = build_elf_exec_info(buf, len, &ehdr, 0);
642+
643+ if (result < 0) {
644+ dbgprintf("Not an ELF executable\n");
645+ goto out;
646+ }
647+
648+ if (ehdr.e_machine != EM_AARCH64) {
649+ dbgprintf("Not an AARCH64 executable\n");
650+ result = -1;
651+ goto out;
652+ }
653+
654+ result = 0;
655+
656+out:
657+ free_elf_info(&ehdr);
658+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
659+ return result;
660+}
661+
662+int elf_arm64_load(int argc, char **argv, const char *buf, off_t len,
663+ struct kexec_info *info)
664+{
665+ static const struct option options[] = {
666+ KEXEC_ARCH_OPTIONS
667+ { 0 }
668+ };
669+ static const char short_options[] = KEXEC_OPT_STR "";
670+ const char *command_line = NULL;
671+ unsigned int command_line_len = 0;
672+ const char *ramdisk = NULL;
673+ const char *dtb = NULL;
674+ int opt;
675+ struct mem_ehdr ehdr;
676+ int result;
677+
678+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
679+
680+ while ((opt = getopt_long(argc, argv, short_options, options, 0))
681+ != -1) {
682+ switch (opt) {
683+ default:
684+ if (opt < OPT_MAX) /* Ignore core options */
685+ break;
686+ case OPT_APPEND:
687+ command_line = optarg;
688+ command_line_len = strlen(command_line) + 1;
689+ break;
690+ case OPT_RAMDISK:
691+ ramdisk = optarg;
692+ break;
693+ case OPT_DTB:
694+ dtb = optarg;
695+ break;
696+ }
697+ }
698+
699+ fprintf(stderr, "%s:%d: command_line: %s\n", __func__, __LINE__, command_line);
700+ fprintf(stderr, "%s:%d: ramdisk: %s\n", __func__, __LINE__, ramdisk);
701+ fprintf(stderr, "%s:%d: dtb: %s\n", __func__, __LINE__, dtb);
702+
703+ if (info->kexec_flags & KEXEC_ON_CRASH) {
704+ fprintf(stderr, "kexec: kdump not yet supported on arm64\n");
705+ return -1;
706+ }
707+
708+ result = build_elf_exec_info(buf, len, &ehdr, 0);
709+
710+ if (result < 0) {
711+ free_elf_info(&ehdr);
712+ fprintf(stderr, "%s:%d: free_elf_info failed\n", __func__,
713+ __LINE__);
714+ return result;
715+ }
716+
717+ elf_exec_build_load(info, &ehdr, buf, len, 0);
718+
719+ info->entry = (void*)0x80080000UL; // FIXME
720+
721+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
722+ return 0;
723+}
724+
725+void elf_arm64_usage(void)
726+{
727+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
728+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
729+}
730Index: kexec-tools-2.0.4/kexec/kexec-syscall.h
731===================================================================
732--- kexec-tools-2.0.4.orig/kexec/kexec-syscall.h
733+++ kexec-tools-2.0.4/kexec/kexec-syscall.h
734@@ -39,8 +39,8 @@
735 #ifdef __s390__
736 #define __NR_kexec_load 277
737 #endif
738-#ifdef __arm__
739-#define __NR_kexec_load __NR_SYSCALL_BASE + 347
740+#if defined(__arm__) || defined(__arm64__)
741+#define __NR_kexec_load __NR_SYSCALL_BASE + 347
742 #endif
743 #if defined(__mips__)
744 #define __NR_kexec_load 4311
745@@ -72,6 +72,8 @@ static inline long kexec_load(void *entr
746 #define KEXEC_ARCH_PPC64 (21 << 16)
747 #define KEXEC_ARCH_IA_64 (50 << 16)
748 #define KEXEC_ARCH_ARM (40 << 16)
749+#define KEXEC_ARCH_ARM64 (183 << 16)
750+/* #define KEXEC_ARCH_AARCH64 (183 << 16) */
751 #define KEXEC_ARCH_S390 (22 << 16)
752 #define KEXEC_ARCH_SH (42 << 16)
753 #define KEXEC_ARCH_MIPS_LE (10 << 16)
754@@ -114,5 +116,8 @@ static inline long kexec_load(void *entr
755 #if defined(__mips__)
756 #define KEXEC_ARCH_NATIVE KEXEC_ARCH_MIPS
757 #endif
758+#if defined(__arm64__)
759+#define KEXEC_ARCH_NATIVE KEXEC_ARCH_ARM64
760+#endif
761
762 #endif /* KEXEC_SYSCALL_H */
763Index: kexec-tools-2.0.4/kexec/kexec.c
764===================================================================
765--- kexec-tools-2.0.4.orig/kexec/kexec.c
766+++ kexec-tools-2.0.4/kexec/kexec.c
767@@ -659,6 +659,8 @@ static int my_load(const char *type, int
768 info.backup_start = 0;
769 info.kexec_flags = kexec_flags;
770
771+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
772+
773 result = 0;
774 if (argc - fileind <= 0) {
775 fprintf(stderr, "No kernel specified\n");
776Index: kexec-tools-2.0.4/purgatory/arch/arm64/Makefile
777===================================================================
778--- /dev/null
779+++ kexec-tools-2.0.4/purgatory/arch/arm64/Makefile
780@@ -0,0 +1,7 @@
781+#
782+# Purgatory arm64
783+#
784+
785+arm64_PURGATORY_SRCS =
786+
787+dist += purgatory/arch/arm64/Makefile $(arm64_PURGATORY_SRCS)
788Index: kexec-tools-2.0.4/configure
789===================================================================
790--- kexec-tools-2.0.4.orig/configure
791+++ kexec-tools-2.0.4/configure
792@@ -2256,6 +2256,9 @@ case $target_cpu in
793 powerpc64 )
794 ARCH="ppc64"
795 ;;
796+ aarch64 )
797+ ARCH="arm64"
798+ ;;
799 arm* )
800 ARCH="arm"
801 ;;
diff --git a/meta/recipes-kernel/kexec/kexec-tools_2.0.8.bb b/meta/recipes-kernel/kexec/kexec-tools_2.0.8.bb
index 559bc6a25d..c478732300 100644
--- a/meta/recipes-kernel/kexec/kexec-tools_2.0.8.bb
+++ b/meta/recipes-kernel/kexec/kexec-tools_2.0.8.bb
@@ -2,7 +2,9 @@ require kexec-tools.inc
2export LDFLAGS = "-L${STAGING_LIBDIR}" 2export LDFLAGS = "-L${STAGING_LIBDIR}"
3EXTRA_OECONF = " --with-zlib=yes" 3EXTRA_OECONF = " --with-zlib=yes"
4 4
5SRC_URI += "file://kexec-tools-Refine-kdump-device_tree-sort.patch" 5SRC_URI += "file://kexec-tools-Refine-kdump-device_tree-sort.patch \
6 file://kexec-aarch64.patch \
7 "
6 8
7SRC_URI[md5sum] = "45bd2bc676ae202579e4c185563126af" 9SRC_URI[md5sum] = "45bd2bc676ae202579e4c185563126af"
8SRC_URI[sha256sum] = "95083c707577154a2241c5af0985f1eb3412d1ba208ef91813e9158b0a901179" 10SRC_URI[sha256sum] = "95083c707577154a2241c5af0985f1eb3412d1ba208ef91813e9158b0a901179"