summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAKASHI Takahiro <takahiro.akashi@linaro.org>2017-04-18 09:27:10 +0900
committerAKASHI Takahiro <takahiro.akashi@linaro.org>2017-08-24 16:29:10 +0900
commit3271c226bd7f6f27e9796476d67b95077debaa34 (patch)
tree413189250af1c32d48729991a6314263c429a3e2
parent1bf6778d3264dfbbeea8b958577eca640ae1e115 (diff)
downloadkexec-tools-arm64/kexec_file.tar.gz
arm64: add kexec_file_load supportarm64/kexec_file
With this patch, kexec_file_load() system call is supported. Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
-rw-r--r--kexec/arch/arm64/kexec-arm64.c10
-rw-r--r--kexec/arch/arm64/kexec-elf-arm64.c23
-rw-r--r--kexec/arch/arm64/kexec-image-arm64.c28
-rw-r--r--kexec/kexec-syscall.h4
4 files changed, 63 insertions, 2 deletions
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index 62f3758..e0f2a56 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -120,6 +120,7 @@ int arch_process_options(int argc, char **argv)
int opt;
char *cmdline = NULL;
const char *append = NULL;
+ int do_kexec_file_syscall = 0;
for (opt = 0; opt != -1; ) {
opt = getopt_long(argc, argv, short_options, options, 0);
@@ -137,6 +138,9 @@ int arch_process_options(int argc, char **argv)
case OPT_INITRD:
arm64_opts.initrd = optarg;
break;
+ case OPT_KEXEC_FILE_SYSCALL:
+ do_kexec_file_syscall = 1;
+ break;
default:
break; /* Ignore core and unknown options. */
}
@@ -148,7 +152,11 @@ int arch_process_options(int argc, char **argv)
arm64_opts.command_line);
dbgprintf("%s:%d: initrd: %s\n", __func__, __LINE__,
arm64_opts.initrd);
- dbgprintf("%s:%d: dtb: %s\n", __func__, __LINE__, arm64_opts.dtb);
+ dbgprintf("%s:%d: dtb: %s\n", __func__, __LINE__,
+ (do_kexec_file_syscall && arm64_opts.dtb ? "(ignored)" :
+ arm64_opts.dtb));
+ if (do_kexec_file_syscall)
+ arm64_opts.dtb = NULL;
return 0;
}
diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c
index fc83b42..0ca3621 100644
--- a/kexec/arch/arm64/kexec-elf-arm64.c
+++ b/kexec/arch/arm64/kexec-elf-arm64.c
@@ -5,10 +5,12 @@
#define _GNU_SOURCE
#include <errno.h>
+#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>
#include <linux/elf.h>
+#include "arch/options.h"
#include "crashdump-arm64.h"
#include "kexec-arm64.h"
#include "kexec-elf.h"
@@ -47,6 +49,27 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf,
int result;
int i;
+ if (info->file_mode) {
+ if (arm64_opts.initrd) {
+ info->initrd_fd = open(arm64_opts.initrd, O_RDONLY);
+ if (info->initrd_fd == -1) {
+ fprintf(stderr,
+ "Could not open initrd file %s:%s\n",
+ arm64_opts.initrd, strerror(errno));
+ result = EFAILED;
+ goto exit;
+ }
+ }
+
+ if (arm64_opts.command_line) {
+ info->command_line = (char *)arm64_opts.command_line;
+ info->command_line_len =
+ strlen(arm64_opts.command_line) + 1;
+ }
+
+ return 0;
+ }
+
result = build_elf_exec_info(kernel_buf, kernel_size, &ehdr, 0);
if (result < 0) {
diff --git a/kexec/arch/arm64/kexec-image-arm64.c b/kexec/arch/arm64/kexec-image-arm64.c
index e1b1e54..9eaf54d 100644
--- a/kexec/arch/arm64/kexec-image-arm64.c
+++ b/kexec/arch/arm64/kexec-image-arm64.c
@@ -4,10 +4,15 @@
#define _GNU_SOURCE
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
#include "crashdump-arm64.h"
+#include "image-header.h"
+#include "kexec.h"
#include "kexec-arm64.h"
#include "kexec-syscall.h"
-#include <limits.h>
+#include "arch/options.h"
int image_arm64_probe(const char *kernel_buf, off_t kernel_size)
{
@@ -35,6 +40,27 @@ int image_arm64_load(int argc, char **argv, const char *kernel_buf,
unsigned long kernel_segment;
int result;
+ if (info->file_mode) {
+ if (arm64_opts.initrd) {
+ info->initrd_fd = open(arm64_opts.initrd, O_RDONLY);
+ if (info->initrd_fd == -1) {
+ fprintf(stderr,
+ "Could not open initrd file %s:%s\n",
+ arm64_opts.initrd, strerror(errno));
+ result = EFAILED;
+ goto exit;
+ }
+ }
+
+ if (arm64_opts.command_line) {
+ info->command_line = (char *)arm64_opts.command_line;
+ info->command_line_len =
+ strlen(arm64_opts.command_line) + 1;
+ }
+
+ return 0;
+ }
+
header = (const struct arm64_image_header *)(kernel_buf);
if (arm64_process_image_header(header))
diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h
index 3b5c528..ef37753 100644
--- a/kexec/kexec-syscall.h
+++ b/kexec/kexec-syscall.h
@@ -61,6 +61,10 @@
#ifdef __x86_64__
#define __NR_kexec_file_load 320
#endif
+/* FIXME: as of v4.13 */
+#ifdef __aarch64__
+#define __NR_kexec_file_load 292
+#endif
#ifndef __NR_kexec_file_load
/* system call not available for the arch */