* [PATCH 1/3] kexec: Move zlib buffer decompression function
2018-07-05 12:55 [PATCH 0/3] arm64: add support for loading kernel from FITimage Arnaud Ferraris
@ 2018-07-05 12:55 ` Arnaud Ferraris
2018-07-05 12:55 ` [PATCH 2/3] kexec: fitImage: Add fitImage parser and loader Arnaud Ferraris
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Arnaud Ferraris @ 2018-07-05 12:55 UTC (permalink / raw)
To: horms, kexec
In order to be able to use this feature throughout kexec-tools,
the uImage_gz_load function is renamed zlib_decompress_buffer and
moved to kexec/zlib.c
Signed-off-by: Arnaud Ferraris <arnaud.ferraris.external@sigfox.com>
---
kexec/kexec-uImage.c | 100 ++-------------------------------------------------
kexec/kexec-zlib.h | 1 +
kexec/zlib.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 104 insertions(+), 97 deletions(-)
diff --git a/kexec/kexec-uImage.c b/kexec/kexec-uImage.c
index eeee4be..51ae486 100644
--- a/kexec/kexec-uImage.c
+++ b/kexec/kexec-uImage.c
@@ -7,6 +7,7 @@
#include <getopt.h>
#include <arch/options.h>
#include "kexec.h"
+#include "kexec-zlib.h"
#include <kexec-uImage.h>
#ifdef HAVE_LIBZ
@@ -127,110 +128,15 @@ int uImage_probe_ramdisk(const char *buf, off_t len, unsigned int arch)
return !(type == IH_TYPE_RAMDISK);
}
-#ifdef HAVE_LIBZ
-/* gzip flag byte */
-#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
-#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
-#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
-#define COMMENT 0x10 /* bit 4 set: file comment present */
-#define RESERVED 0xE0 /* bits 5..7: reserved */
-
static int uImage_gz_load(const char *buf, off_t len,
struct Image_info *image)
{
- int ret;
- z_stream strm;
- unsigned int skip;
- unsigned int flags;
- unsigned char *uncomp_buf;
- unsigned int mem_alloc;
-
- mem_alloc = 10 * 1024 * 1024;
- uncomp_buf = malloc(mem_alloc);
- if (!uncomp_buf)
- return -1;
-
- memset(&strm, 0, sizeof(strm));
-
- /* Skip magic, method, time, flags, os code ... */
- skip = 10;
-
- /* check GZ magic */
- if (buf[0] != 0x1f || buf[1] != 0x8b)
+ image->buf = zlib_decompress_buffer(buf, len, &image->len);
+ if (!image->buf)
return -1;
- flags = buf[3];
- if (buf[2] != Z_DEFLATED || (flags & RESERVED) != 0) {
- puts ("Error: Bad gzipped data\n");
- return -1;
- }
-
- if (flags & EXTRA_FIELD) {
- skip += 2;
- skip += buf[10];
- skip += buf[11] << 8;
- }
- if (flags & ORIG_NAME) {
- while (buf[skip++])
- ;
- }
- if (flags & COMMENT) {
- while (buf[skip++])
- ;
- }
- if (flags & HEAD_CRC)
- skip += 2;
-
- strm.avail_in = len - skip;
- strm.next_in = (void *)buf + skip;
-
- /* - activates parsing gz headers */
- ret = inflateInit2(&strm, -MAX_WBITS);
- if (ret != Z_OK)
- return -1;
-
- strm.next_out = uncomp_buf;
- strm.avail_out = mem_alloc;
-
- do {
- ret = inflate(&strm, Z_FINISH);
- if (ret == Z_STREAM_END)
- break;
-
- if (ret == Z_OK || ret == Z_BUF_ERROR) {
- void *new_buf;
- int inc_buf = 5 * 1024 * 1024;
-
- mem_alloc += inc_buf;
- new_buf = realloc(uncomp_buf, mem_alloc);
- if (!new_buf) {
- inflateEnd(&strm);
- free(uncomp_buf);
- return -1;
- }
-
- uncomp_buf = new_buf;
- strm.next_out = uncomp_buf + mem_alloc - inc_buf;
- strm.avail_out = inc_buf;
- } else {
- printf("Error during decompression %d\n", ret);
- return -1;
- }
- } while (1);
-
- inflateEnd(&strm);
- image->buf = (char *)uncomp_buf;
- image->len = mem_alloc - strm.avail_out;
return 0;
}
-#else
-static int uImage_gz_load(const char *UNUSED(buf), off_t UNUSED(len),
- struct Image_info *UNUSED(image))
-{
- return -1;
-}
-#endif
int uImage_load(const char *buf, off_t len, struct Image_info *image)
{
diff --git a/kexec/kexec-zlib.h b/kexec/kexec-zlib.h
index 43c107b..ebb1cae 100644
--- a/kexec/kexec-zlib.h
+++ b/kexec/kexec-zlib.h
@@ -7,4 +7,5 @@
#include "config.h"
char *zlib_decompress_file(const char *filename, off_t *r_size);
+char *zlib_decompress_buffer(const char *buffer, off_t len, off_t *r_size);
#endif /* __KEXEC_ZLIB_H */
diff --git a/kexec/zlib.c b/kexec/zlib.c
index 95b6080..9b58f2a 100644
--- a/kexec/zlib.c
+++ b/kexec/zlib.c
@@ -15,6 +15,14 @@
#include <ctype.h>
#include <zlib.h>
+/* gzip flag byte */
+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define COMMENT 0x10 /* bit 4 set: file comment present */
+#define RESERVED 0xE0 /* bits 5..7: reserved */
+
static void _gzerror(gzFile fp, int *errnum, const char **errmsg)
{
*errmsg = gzerror(fp, errnum);
@@ -83,9 +91,101 @@ fail:
}
return buf;
}
+
+char *zlib_decompress_buffer(const char *buffer, off_t len, off_t *r_size)
+{
+ int ret;
+ z_stream strm;
+ unsigned int skip;
+ unsigned int flags;
+ unsigned char *uncomp_buf;
+ unsigned int mem_alloc;
+
+ mem_alloc = 10 * 1024 * 1024;
+ uncomp_buf = malloc(mem_alloc);
+ if (!uncomp_buf)
+ return NULL;
+
+ memset(&strm, 0, sizeof(strm));
+
+ /* Skip magic, method, time, flags, os code ... */
+ skip = 10;
+
+ /* check GZ magic */
+ if (buffer[0] != 0x1f || buffer[1] != 0x8b)
+ return NULL;
+
+ flags = buffer[3];
+ if (buffer[2] != Z_DEFLATED || (flags & RESERVED) != 0) {
+ puts ("Error: Bad gzipped data\n");
+ return NULL;
+ }
+
+ if (flags & EXTRA_FIELD) {
+ skip += 2;
+ skip += buffer[10];
+ skip += buffer[11] << 8;
+ }
+ if (flags & ORIG_NAME) {
+ while (buffer[skip++])
+ ;
+ }
+ if (flags & COMMENT) {
+ while (buffer[skip++])
+ ;
+ }
+ if (flags & HEAD_CRC)
+ skip += 2;
+
+ strm.avail_in = len - skip;
+ strm.next_in = (void *)buffer + skip;
+
+ /* - activates parsing gz headers */
+ ret = inflateInit2(&strm, -MAX_WBITS);
+ if (ret != Z_OK)
+ return NULL;
+
+ strm.next_out = uncomp_buf;
+ strm.avail_out = mem_alloc;
+
+ do {
+ ret = inflate(&strm, Z_FINISH);
+ if (ret == Z_STREAM_END)
+ break;
+
+ if (ret == Z_OK || ret == Z_BUF_ERROR) {
+ void *new_buf;
+ int inc_buf = 5 * 1024 * 1024;
+
+ mem_alloc += inc_buf;
+ new_buf = realloc(uncomp_buf, mem_alloc);
+ if (!new_buf) {
+ inflateEnd(&strm);
+ free(uncomp_buf);
+ return NULL;
+ }
+
+ uncomp_buf = new_buf;
+ strm.next_out = uncomp_buf + mem_alloc - inc_buf;
+ strm.avail_out = inc_buf;
+ } else {
+ printf("Error during decompression %d\n", ret);
+ return NULL;
+ }
+ } while (1);
+
+ inflateEnd(&strm);
+ *r_size = mem_alloc - strm.avail_out;
+ return (char *)uncomp_buf;
+}
#else
char *zlib_decompress_file(const char *UNUSED(filename), off_t *UNUSED(r_size))
{
return NULL;
}
+
+char *zlib_decompress_buffer(const char *UNUSED(buffer), off_t UNUSED(len), off_t *UNUSED(r_size))
+{
+ return NULL;
+}
#endif /* HAVE_ZLIB */
--
2.7.4
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 2/3] kexec: fitImage: Add fitImage parser and loader
2018-07-05 12:55 [PATCH 0/3] arm64: add support for loading kernel from FITimage Arnaud Ferraris
2018-07-05 12:55 ` [PATCH 1/3] kexec: Move zlib buffer decompression function Arnaud Ferraris
@ 2018-07-05 12:55 ` Arnaud Ferraris
2018-07-05 12:55 ` [PATCH 3/3] kexec: arm64: Add fitImage support Arnaud Ferraris
2018-07-06 6:37 ` [PATCH 0/3] arm64: add support for loading kernel from FITimage Bhupesh Sharma
3 siblings, 0 replies; 7+ messages in thread
From: Arnaud Ferraris @ 2018-07-05 12:55 UTC (permalink / raw)
To: horms, kexec
Signed-off-by: Arnaud Ferraris <arnaud.ferraris.external@sigfox.com>
---
include/Makefile | 1 +
include/kexec-fitImage.h | 18 ++++
kexec/Makefile | 4 +
kexec/kexec-fitImage.c | 223 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 246 insertions(+)
create mode 100644 include/kexec-fitImage.h
create mode 100644 kexec/kexec-fitImage.c
diff --git a/include/Makefile b/include/Makefile
index c26b503..5a40001 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -2,6 +2,7 @@ dist += include/Makefile \
include/config.h \
include/config.h.in \
include/kexec-uImage.h \
+ include/kexec-fitImage.h \
include/x86/x86-linux.h \
include/x86/mb_info.h \
include/x86/mb_header.h \
diff --git a/include/kexec-fitImage.h b/include/kexec-fitImage.h
new file mode 100644
index 0000000..0850059
--- /dev/null
+++ b/include/kexec-fitImage.h
@@ -0,0 +1,18 @@
+#ifndef __KEXEC_FITIMAGE_H__
+#define __KEXEC_FITIMAGE_H__
+
+#include <libfdt.h>
+#include <sys/types.h>
+
+struct FitImage_contents {
+ const char *kernel;
+ off_t kernel_size;
+ const char *initrd;
+ off_t initrd_size;
+ const char *dtb;
+ off_t dtb_size;
+};
+
+int fitImage_probe(const char *buf, off_t len, unsigned int arch);
+int fitImage_load(const char *buf, off_t len, struct FitImage_contents *info);
+#endif
diff --git a/kexec/Makefile b/kexec/Makefile
index 4db84d8..5116378 100644
--- a/kexec/Makefile
+++ b/kexec/Makefile
@@ -67,6 +67,10 @@ dist += kexec/kexec-uImage.c
$(ARCH)_UIMAGE =
KEXEC_SRCS += $($(ARCH)_UIMAGE)
+dist += kexec/kexec-fitImage.c
+$(ARCH)_FITIMAGE =
+KEXEC_SRCS += $($(ARCH)_FITIMAGE)
+
dist += kexec/fs2dt.c kexec/fs2dt.h
$(ARCH)_FS2DT =
KEXEC_SRCS += $($(ARCH)_FS2DT)
diff --git a/kexec/kexec-fitImage.c b/kexec/kexec-fitImage.c
new file mode 100644
index 0000000..90cf81a
--- /dev/null
+++ b/kexec/kexec-fitImage.c
@@ -0,0 +1,223 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <image.h>
+#include <getopt.h>
+#include <arch/options.h>
+#include "kexec.h"
+#include "kexec-zlib.h"
+#include <kexec-fitImage.h>
+
+/*
+ * fitImage parser and loader.
+ *
+ * The fitImage format is based on the device tree, with 2 top-level nodes:
+ * - configurations: contains a list of configurations, each config containing
+ * at least a kernel, and optionally a device tree and/or initrd
+ * - images: contains the binary data, each image being either a kernel
+ * device tree or initrd file
+ * The /configurations node has a "default" property stating the subnode name
+ * of the default config.
+ * Each image has its own subnode under /images containing at least the
+ * following properties:
+ * - data: the binary data blob
+ * - comp: the compression type used (for now, only "gzip" is implemented here)
+ * Other image nodes properties (architecture, OS type, has/signature...)
+ * are not processed here (at least for now) as they are not mandatory for
+ * extracting the image files.
+ */
+
+static const char *fitImage_find_default_conf(const char *fit)
+{
+ int offset;
+
+ /* Find default configuration */
+ offset = fdt_subnode_offset(fit, 0, "configurations");
+ if (offset > 0)
+ return fdt_getprop(fit, offset, "default", NULL);
+ else
+ fprintf(stderr, "kexec: unable to find configurations\n");
+
+ return NULL;
+}
+
+static const char *fitImage_get_config_property(const char *fit,
+ const char *config, const char *name)
+{
+ int offset;
+
+ /* Find default configuration */
+ offset = fdt_subnode_offset(fit, 0, "configurations");
+ if (offset > 0) {
+ offset = fdt_subnode_offset(fit, offset, config);
+ if (offset > 0)
+ return fdt_getprop(fit, offset, name, NULL);
+ else {
+ fprintf(stderr, "kexec: unable to find configuration '%s'\n",
+ config);
+ }
+ }
+ else
+ fprintf(stderr, "kexec: unable to find configurations\n");
+
+ return NULL;
+}
+
+static const struct fdt_property *fitImage_get_image_property(const char *fit,
+ const char *image, const char *property)
+{
+ int offset;
+
+ /* Find images node */
+ offset = fdt_subnode_offset(fit, 0, "images");
+ if (offset > 0) {
+ offset = fdt_subnode_offset(fit, offset, image);
+ if (offset > 0)
+ return fdt_get_property(fit, offset, property, NULL);
+ else {
+ fprintf(stderr, "kexec: unable to find image '%s'\n",
+ image);
+ }
+ }
+ else
+ fprintf(stderr, "kexec: unable to find images\n");
+
+ return NULL;
+}
+
+static const char *fitImage_get_image_data(const char *fit, const char *image,
+ uint32_t *size)
+{
+ const struct fdt_property *image_prop;
+
+ image_prop = fitImage_get_image_property(fit, image, "data");
+ if (image_prop) {
+ *size = be32_to_cpu(image_prop->len);
+ return image_prop->data;
+ }
+ else
+ fprintf(stderr, "kexec: unable to get image '%s' data\n", image);
+
+ return NULL;
+}
+
+static int fitImage_get_image_comp(const char *fit, const char *image)
+{
+ const struct fdt_property *image_prop;
+
+ image_prop = fitImage_get_image_property(fit, image, "compression");
+ if (image_prop && image_prop->len > 0) {
+ if (strcmp(image_prop->data, "gzip") == 0)
+ return IH_COMP_GZIP;
+ }
+ else {
+ fprintf(stderr, "kexec: unable to get image '%s' compression\n",
+ image);
+ }
+
+ return IH_COMP_NONE;
+}
+
+static const char *fitImage_get_image(const char *fit, const char *name,
+ off_t *size)
+{
+ uint32_t image_size;
+ int comp, fd;
+ const char *data;
+ const char *image;
+
+ data = fitImage_get_image_data(fit, name, &image_size);
+ comp = fitImage_get_image_comp(fit, name);
+ if (data) {
+ switch(comp) {
+ case IH_COMP_NONE:
+ image = data;
+ *size = image_size;
+ break;
+ case IH_COMP_GZIP:
+ image = zlib_decompress_buffer(data, image_size, size);
+ break;
+ default:
+ image = NULL;
+ *size = 0;
+ break;
+ }
+ }
+
+ return image;
+}
+
+/*
+ * Returns 0 if the image could be succesfully parsed as a fitImage.
+ *
+ * Returns -1 if this is not a fitImage or a corrupted image
+ */
+int fitImage_probe(const char *buf, off_t len, unsigned int arch)
+{
+ uint32_t kernel_size;
+ const char *kernel_data;
+ const char *kernel_name;
+ const char *default_config;
+
+ default_config = fitImage_find_default_conf(buf);
+ if (!default_config)
+ return -1;
+
+ kernel_name = fitImage_get_config_property(buf, default_config, "kernel");
+ if (!kernel_name)
+ return -1;
+
+ kernel_data = fitImage_get_image_data(buf, kernel_name, &kernel_size);
+ if (!kernel_data)
+ return -1;
+
+ return 0;
+}
+
+int fitImage_load(const char *buf, off_t len, struct FitImage_contents *image)
+{
+ uint32_t image_size;
+ int image_comp, fd;
+ const char *image_data;
+ const char *image_name;
+ const char *default_config;
+
+ default_config = fitImage_find_default_conf(buf);
+ if (!default_config) {
+ fprintf(stderr, "kexec: no default configuration in fitImage\n");
+ return -1;
+ }
+
+ /* Load kernel (mandatory) */
+ image_name = fitImage_get_config_property(buf, default_config, "kernel");
+ if (image_name) {
+ image->kernel = fitImage_get_image(buf,
+ image_name, &image->kernel_size);
+ }
+
+ if (!image->kernel) {
+ fprintf(stderr, "kexec: unable to load kernel from fitImage\n");
+ return -1;
+ }
+
+ /* Load ramdisk if present */
+ image_name = fitImage_get_config_property(buf, default_config, "ramdisk");
+ if (image_name) {
+ image->initrd = fitImage_get_image(buf,
+ image_name, &image->initrd_size);
+ }
+
+ /* Load device tree if present */
+ image_name = fitImage_get_config_property(buf, default_config, "fdt");
+ if (image_name) {
+ image->dtb = fitImage_get_image(buf,
+ image_name, &image->dtb_size);
+ }
+
+ return 0;
+}
--
2.7.4
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 3/3] kexec: arm64: Add fitImage support
2018-07-05 12:55 [PATCH 0/3] arm64: add support for loading kernel from FITimage Arnaud Ferraris
2018-07-05 12:55 ` [PATCH 1/3] kexec: Move zlib buffer decompression function Arnaud Ferraris
2018-07-05 12:55 ` [PATCH 2/3] kexec: fitImage: Add fitImage parser and loader Arnaud Ferraris
@ 2018-07-05 12:55 ` Arnaud Ferraris
2018-07-06 6:37 ` [PATCH 0/3] arm64: add support for loading kernel from FITimage Bhupesh Sharma
3 siblings, 0 replies; 7+ messages in thread
From: Arnaud Ferraris @ 2018-07-05 12:55 UTC (permalink / raw)
To: horms, kexec
Signed-off-by: Arnaud Ferraris <arnaud.ferraris.external@sigfox.com>
---
kexec/arch/arm64/Makefile | 2 ++
kexec/arch/arm64/kexec-arm64.c | 15 +++++++++++--
kexec/arch/arm64/kexec-arm64.h | 4 ++++
kexec/arch/arm64/kexec-fitImage-arm64.c | 40 +++++++++++++++++++++++++++++++++
kexec/kexec.h | 4 ++++
5 files changed, 63 insertions(+), 2 deletions(-)
create mode 100644 kexec/arch/arm64/kexec-fitImage-arm64.c
diff --git a/kexec/arch/arm64/Makefile b/kexec/arch/arm64/Makefile
index 9d9111c..e33209e 100644
--- a/kexec/arch/arm64/Makefile
+++ b/kexec/arch/arm64/Makefile
@@ -15,9 +15,11 @@ arm64_KEXEC_SRCS += \
kexec/arch/arm64/kexec-arm64.c \
kexec/arch/arm64/kexec-elf-arm64.c \
kexec/arch/arm64/kexec-uImage-arm64.c \
+ kexec/arch/arm64/kexec-fitImage-arm64.c \
kexec/arch/arm64/kexec-image-arm64.c
arm64_UIMAGE = kexec/kexec-uImage.c
+arm64_FITIMAGE = kexec/kexec-fitImage.c
arm64_ARCH_REUSE_INITRD =
arm64_ADD_SEGMENT =
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index 7a12479..344037c 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -55,6 +55,8 @@ struct file_type file_type[] = {
{"vmlinux", elf_arm64_probe, elf_arm64_load, elf_arm64_usage},
{"Image", image_arm64_probe, image_arm64_load, image_arm64_usage},
{"uImage", uImage_arm64_probe, uImage_arm64_load, uImage_arm64_usage},
+ {"fitImage", fitImage_arm64_probe, fitImage_arm64_load,
+ fitImage_arm64_usage},
};
int file_types = sizeof(file_type) / sizeof(file_type[0]);
@@ -613,6 +615,10 @@ int arm64_load_other_segments(struct kexec_info *info,
if (arm64_opts.dtb) {
dtb.name = "dtb_user";
dtb.buf = slurp_file(arm64_opts.dtb, &dtb.size);
+ } else if (info->dtb) {
+ dtb.name = "dtb_user";
+ dtb.buf = info->dtb;
+ dtb.size = info->dtb_size;
} else {
result = read_1st_dtb(&dtb);
@@ -637,8 +643,13 @@ int arm64_load_other_segments(struct kexec_info *info,
else
hole_max = ULONG_MAX;
- if (arm64_opts.initrd) {
- initrd_buf = slurp_file(arm64_opts.initrd, &initrd_size);
+ if (arm64_opts.initrd || info->initrd) {
+ if (arm64_opts.initrd)
+ initrd_buf = slurp_file(arm64_opts.initrd, &initrd_size);
+ else {
+ initrd_buf = info->initrd;
+ initrd_size = info->initrd_size;
+ }
if (!initrd_buf)
fprintf(stderr, "kexec: Empty ramdisk file.\n");
diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h
index 22e4b69..cd05b0b 100644
--- a/kexec/arch/arm64/kexec-arm64.h
+++ b/kexec/arch/arm64/kexec-arm64.h
@@ -34,6 +34,10 @@ int uImage_arm64_probe(const char *buf, off_t len);
int uImage_arm64_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void uImage_arm64_usage(void);
+int fitImage_arm64_probe(const char *buf, off_t len);
+int fitImage_arm64_load(int argc, char **argv, const char *buf, off_t len,
+ struct kexec_info *info);
+void fitImage_arm64_usage(void);
off_t initrd_base;
off_t initrd_size;
diff --git a/kexec/arch/arm64/kexec-fitImage-arm64.c b/kexec/arch/arm64/kexec-fitImage-arm64.c
new file mode 100644
index 0000000..1085f1b
--- /dev/null
+++ b/kexec/arch/arm64/kexec-fitImage-arm64.c
@@ -0,0 +1,40 @@
+/*
+ * fitImage support for ARM64
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <image.h>
+#include <kexec-fitImage.h>
+#include "../../kexec.h"
+#include "kexec-arm64.h"
+
+int fitImage_arm64_probe(const char *buf, off_t len)
+{
+ return fitImage_probe(buf, len, IH_ARCH_ARM64);
+}
+
+int fitImage_arm64_load(int argc, char **argv, const char *buf, off_t len,
+ struct kexec_info *info)
+{
+ struct FitImage_contents img;
+ int ret;
+
+ ret = fitImage_load(buf, len, &img);
+ if (ret)
+ return ret;
+
+ info->initrd = img.initrd;
+ info->initrd_size = img.initrd_size;
+ info->dtb = img.dtb;
+ info->dtb_size = img.dtb_size;
+
+ return image_arm64_load(argc, argv, img.kernel, img.kernel_size, info);
+}
+
+void fitImage_arm64_usage(void)
+{
+ printf(
+" An ARM64 fitImage file, compressed or not, big or little endian.\n\n");
+}
diff --git a/kexec/kexec.h b/kexec/kexec.h
index a97b9ce..19a807a 100644
--- a/kexec/kexec.h
+++ b/kexec/kexec.h
@@ -166,6 +166,10 @@ struct kexec_info {
int initrd_fd;
char *command_line;
int command_line_len;
+ const char *initrd;
+ off_t initrd_size;
+ const char *dtb;
+ off_t dtb_size;
int skip_checks;
};
--
2.7.4
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH 0/3] arm64: add support for loading kernel from FITimage
2018-07-05 12:55 [PATCH 0/3] arm64: add support for loading kernel from FITimage Arnaud Ferraris
` (2 preceding siblings ...)
2018-07-05 12:55 ` [PATCH 3/3] kexec: arm64: Add fitImage support Arnaud Ferraris
@ 2018-07-06 6:37 ` Bhupesh Sharma
2018-07-06 14:39 ` Arnaud Ferraris
3 siblings, 1 reply; 7+ messages in thread
From: Bhupesh Sharma @ 2018-07-06 6:37 UTC (permalink / raw)
To: Arnaud Ferraris; +Cc: Simon Horman, kexec mailing list
Hello Arnaud,
Thanks for the patch.
On Thu, Jul 5, 2018 at 6:25 PM, Arnaud Ferraris
<arnaud.ferraris.external@sigfox.com> wrote:
> Hi all,
>
> FITimages are an image format used by U-boot, allowing to embed a kernel with
> the associated device tree and initramfs into a single file, using the device
> tree file format.
> Unfortunately, for now kexec doesn't recognize the FITimage format.
Hmm, I think I mentioned this earlier, but why do we need kexec to
support the FIT image format? See the FIT image (or the .itb file)
will be parsed by the u-boot bootloader and the respective components
will be loaded by it at the appropriate load addresses (for the kernel
Image it would be the load address mentioned in the 'loadaddr' u-boot
environment variable and for the dtb it would be as per the arm64
architecture dtb offset placement constraints). Something like (which
I copied from logs on my arm32 board):
<..snip..>
kernel loaded at 0x80008000, end = 0x802bddd0
Loading Device Tree to 8fe44000, end 8fe49947 ... OK
Starting kernel ...
<..snip..>
So, the images are already placed at appropriate addresses by u-boot
and we simply do the following at the u-boot prompt:
<u-boot> bootm ${loadaddr}
So, I am trying to understand the use-case behind FIT image support in
kexec. Do we need kexec-tools to be aware of the FIT format when the
kernel itself it loaded in an uncompressed format (e.g. Image or
vmlinux).
If you can share your .its file and explain the use case better (may
be with the u-boot logs) it would help in the review.
I have other comments on the individual patches, but I will hold them
till the problem we are trying to solve here is clearer to me.
Thanks,
Bhupesh
> This patchset adds a generic FITimage loader & parser, and implements loading
> a kernel/dtb/initrd for the ARM64 architecture.
>
> Arnaud Ferraris (3):
> kexec: Move zlib buffer decompression function
> kexec: fitImage: Add fitImage parser and loader
> kexec: arm64: Add fitImage support
>
> include/Makefile | 1 +
> include/kexec-fitImage.h | 18 +++
> kexec/Makefile | 4 +
> kexec/arch/arm64/Makefile | 2 +
> kexec/arch/arm64/kexec-arm64.c | 15 ++-
> kexec/arch/arm64/kexec-arm64.h | 4 +
> kexec/arch/arm64/kexec-fitImage-arm64.c | 40 ++++++
> kexec/kexec-fitImage.c | 223 ++++++++++++++++++++++++++++++++
> kexec/kexec-uImage.c | 100 +-------------
> kexec/kexec-zlib.h | 1 +
> kexec/kexec.h | 4 +
> kexec/zlib.c | 100 ++++++++++++++
> 12 files changed, 413 insertions(+), 99 deletions(-)
> create mode 100644 include/kexec-fitImage.h
> create mode 100644 kexec/arch/arm64/kexec-fitImage-arm64.c
> create mode 100644 kexec/kexec-fitImage.c
>
> --
> 2.7.4
>
>
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH 0/3] arm64: add support for loading kernel from FITimage
2018-07-06 6:37 ` [PATCH 0/3] arm64: add support for loading kernel from FITimage Bhupesh Sharma
@ 2018-07-06 14:39 ` Arnaud Ferraris
2018-07-27 8:17 ` Arnaud Ferraris
0 siblings, 1 reply; 7+ messages in thread
From: Arnaud Ferraris @ 2018-07-06 14:39 UTC (permalink / raw)
To: Bhupesh Sharma; +Cc: Simon Horman, kexec mailing list
Hello Bhupesh,
Thanks for your answer.
On 06/07/2018 08:37, Bhupesh Sharma wrote:
> Hmm, I think I mentioned this earlier, but why do we need kexec to
> support the FIT image format? See the FIT image (or the .itb file)
> will be parsed by the u-boot bootloader and the respective components
> will be loaded by it at the appropriate load addresses (for the kernel
> Image it would be the load address mentioned in the 'loadaddr' u-boot
> environment variable and for the dtb it would be as per the arm64
> architecture dtb offset placement constraints).
>
> <...>
>
> So, I am trying to understand the use-case behind FIT image support in
> kexec. Do we need kexec-tools to be aware of the FIT format when the
> kernel itself it loaded in an uncompressed format (e.g. Image or
> vmlinux).
Ok, I'll do my best to explain our use case : U-boot indeed does a great
job at parsing and loading the FIT image components at the appropriate
addresses.
However, we use kexec (with option -p) to load a crash kernel to be executed
in case of a panic. Moreover, we need to load this kernel along with its own
dtb AND initrd (the initrd is very important, as it contains a special boot
script which uses makedumpfile to create a dump of the crashed kernel for
further analysis).
The FIT image we load through kexec is not necessarily the same as the one
we load through u-boot, the initrd being different, but the kernel and dtb
could be specific too.
All in all, this could be done by using a uImage for the kernel+dtb and a
separate initrd file, but this is not an option in our case, due to the
number of devices and architectures our build system supports, which is why
we need this FIT image support.
> If you can share your .its file and explain the use case better (may
> be with the u-boot logs) it would help in the review.
Sure, the .its file contents follow.
Best regards,
Arnaud
---
/dts-v1/;
/ {
description = "U-Boot fitImage for SIGFOX TapOS/4.14.29+gitAUTOINC+8096079403/a3700";
#address-cells = <1>;
images {
kernel@1 {
description = "Linux kernel";
data = /incbin/("linux.bin");
type = "kernel";
arch = "arm64";
os = "linux";
compression = "gzip";
load = <0x00080000>;
entry = <0x00080000>;
hash@1 {
algo = "sha256";
};
};
fdt@sigfox_sigfox-bs-a3700.dtb {
description = "Flattened Device Tree blob";
data = /incbin/("arch/arm64/boot/dts/sigfox/sigfox-bs-a3700.dtb");
type = "flat_dt";
arch = "arm64";
compression = "none";
load = <0x01800000>;
hash@1 {
algo = "sha256";
};
};
ramdisk@1 {
description = "tapos-image-initramfs";
data = /incbin/(<path/to/initrd>);
type = "ramdisk";
arch = "arm64";
os = "linux";
compression = "gzip";
load = <0x02000000>;
entry = <0x02000000>;
hash@1 {
algo = "sha256";
};
};
};
configurations {
default = "conf@sigfox_sigfox-bs-a3700.dtb";
conf@sigfox_sigfox-bs-a3700.dtb {
description = "1 Linux kernel, FDT blob, ramdisk";
kernel = "kernel@1";
fdt = "fdt@sigfox_sigfox-bs-a3700.dtb";
ramdisk = "ramdisk@1";
hash@1 {
algo = "sha256";
};
signature@1 {
algo = "sha256,rsa2048";
key-name-hint = "kernel";
sign-images = "kernel", "fdt", "ramdisk";
};
};
};
};
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH 0/3] arm64: add support for loading kernel from FITimage
2018-07-06 14:39 ` Arnaud Ferraris
@ 2018-07-27 8:17 ` Arnaud Ferraris
0 siblings, 0 replies; 7+ messages in thread
From: Arnaud Ferraris @ 2018-07-27 8:17 UTC (permalink / raw)
To: Bhupesh Sharma; +Cc: Thomas Perrot, Simon Horman, kexec mailing list
Hello Bhupesh,
Did you have a chance to have a look at my email ?
Moreover, I'm addind Thomas Perrot to the conversation, as he wil be
taking over my work at Sigfox, and will most probably want to follow
this matter.
Best regards,
Arnaud
On 06/07/2018 16:39, Arnaud Ferraris wrote:
> Hello Bhupesh,
>
> Thanks for your answer.
>
> On 06/07/2018 08:37, Bhupesh Sharma wrote:
>> Hmm, I think I mentioned this earlier, but why do we need kexec to
>> support the FIT image format? See the FIT image (or the .itb file)
>> will be parsed by the u-boot bootloader and the respective components
>> will be loaded by it at the appropriate load addresses (for the kernel
>> Image it would be the load address mentioned in the 'loadaddr' u-boot
>> environment variable and for the dtb it would be as per the arm64
>> architecture dtb offset placement constraints).
>>
>> <...>
>>
>> So, I am trying to understand the use-case behind FIT image support in
>> kexec. Do we need kexec-tools to be aware of the FIT format when the
>> kernel itself it loaded in an uncompressed format (e.g. Image or
>> vmlinux).
>
> Ok, I'll do my best to explain our use case : U-boot indeed does a great
> job at parsing and loading the FIT image components at the appropriate
> addresses.
>
> However, we use kexec (with option -p) to load a crash kernel to be
> executed
> in case of a panic. Moreover, we need to load this kernel along with
> its own
> dtb AND initrd (the initrd is very important, as it contains a special
> boot
> script which uses makedumpfile to create a dump of the crashed kernel for
> further analysis).
>
> The FIT image we load through kexec is not necessarily the same as the
> one
> we load through u-boot, the initrd being different, but the kernel and
> dtb
> could be specific too.
>
> All in all, this could be done by using a uImage for the kernel+dtb and a
> separate initrd file, but this is not an option in our case, due to the
> number of devices and architectures our build system supports, which
> is why
> we need this FIT image support.
>
>> If you can share your .its file and explain the use case better (may
>> be with the u-boot logs) it would help in the review.
>
> Sure, the .its file contents follow.
>
> Best regards,
>
> Arnaud
>
> ---
> /dts-v1/;
>
> / {
> description = "U-Boot fitImage for SIGFOX
> TapOS/4.14.29+gitAUTOINC+8096079403/a3700";
> #address-cells = <1>;
>
> images {
> kernel@1 {
> description = "Linux kernel";
> data = /incbin/("linux.bin");
> type = "kernel";
> arch = "arm64";
> os = "linux";
> compression = "gzip";
> load = <0x00080000>;
> entry = <0x00080000>;
> hash@1 {
> algo = "sha256";
> };
> };
> fdt@sigfox_sigfox-bs-a3700.dtb {
> description = "Flattened Device Tree blob";
> data =
> /incbin/("arch/arm64/boot/dts/sigfox/sigfox-bs-a3700.dtb");
> type = "flat_dt";
> arch = "arm64";
> compression = "none";
> load = <0x01800000>;
> hash@1 {
> algo = "sha256";
> };
> };
> ramdisk@1 {
> description = "tapos-image-initramfs";
> data = /incbin/(<path/to/initrd>);
> type = "ramdisk";
> arch = "arm64";
> os = "linux";
> compression = "gzip";
> load = <0x02000000>;
> entry = <0x02000000>;
> hash@1 {
> algo = "sha256";
> };
> };
> };
>
> configurations {
> default = "conf@sigfox_sigfox-bs-a3700.dtb";
> conf@sigfox_sigfox-bs-a3700.dtb {
> description = "1 Linux kernel, FDT blob, ramdisk";
> kernel = "kernel@1";
> fdt = "fdt@sigfox_sigfox-bs-a3700.dtb";
> ramdisk = "ramdisk@1";
>
> hash@1 {
> algo = "sha256";
> };
> signature@1 {
> algo = "sha256,rsa2048";
> key-name-hint = "kernel";
> sign-images = "kernel", "fdt", "ramdisk";
> };
> };
> };
> };
>
>
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 7+ messages in thread