From 7ee05eddf184764de8aa1e015936a42d069893f2 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Thu, 26 Apr 2018 09:35:13 +0200 Subject: util/cbfstool: Support FIT payloads In order to support booting a GNU/Linux payload on non x86, the FIT format should be used, as it is the defacto standard on ARM. Due to greater complexity of FIT it is not converted to simple ELF format. Add support for autodecting FIT payloads and add them as new CBFS_TYPE 'fit'. The payload is included as is, with no special header. The code can determine the type at runtime using the CBFS_TYPE field. Support for parsing FIT payloads in coreboot is added in a follow on commit. Compression of FIT payloads is not supported, as the FIT sections might be compressed itself. Starting at this point a CBFS payload/ can be either of type FIT or SELF. Tested on Cavium SoC. Change-Id: Ic5fc30cd5419eb76c4eb50cca3449caea60270de Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/25860 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- payloads/coreinfo/cbfs_module.c | 4 +++ payloads/libpayload/include/cbfs_core.h | 1 + src/commonlib/include/commonlib/cbfs_serialized.h | 1 + util/cbfstool/cbfs-mkpayload.c | 37 +++++++++++++++++++++++ util/cbfstool/cbfs.h | 2 ++ util/cbfstool/cbfstool.c | 9 +++++- util/cbfstool/common.h | 2 ++ util/cbfstool/fdt.h | 34 +++++++++++++++++++++ util/nvramtool/cbfs.h | 1 + 9 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 util/cbfstool/fdt.h diff --git a/payloads/coreinfo/cbfs_module.c b/payloads/coreinfo/cbfs_module.c index ee759352bf..275c84e986 100644 --- a/payloads/coreinfo/cbfs_module.c +++ b/payloads/coreinfo/cbfs_module.c @@ -29,6 +29,7 @@ #define COMPONENT_CBFSHEADER 0x02 #define COMPONENT_STAGE 0x10 #define COMPONENT_SELF 0x20 +#define COMPONENT_FIT 0x21 #define COMPONENT_OPTIONROM 0x30 #define COMPONENT_RAW 0x50 #define COMPONENT_MICROCODE 0x53 @@ -190,6 +191,9 @@ static int cbfs_module_redraw(WINDOW * win) case COMPONENT_SELF: mvwprintw(win, row++, 38, "simple ELF"); break; + case COMPONENT_FIT: + mvwprintw(win, row++, 38, "FIT"); + break; case COMPONENT_OPTIONROM: mvwprintw(win, row++, 38, "optionrom"); break; diff --git a/payloads/libpayload/include/cbfs_core.h b/payloads/libpayload/include/cbfs_core.h index da9860458c..364f6c474d 100644 --- a/payloads/libpayload/include/cbfs_core.h +++ b/payloads/libpayload/include/cbfs_core.h @@ -68,6 +68,7 @@ #define CBFS_TYPE_STAGE 0x10 #define CBFS_TYPE_SELF 0x20 +#define CBFS_TYPE_FIT 0x21 #define CBFS_TYPE_OPTIONROM 0x30 #define CBFS_TYPE_BOOTSPLASH 0x40 #define CBFS_TYPE_RAW 0x50 diff --git a/src/commonlib/include/commonlib/cbfs_serialized.h b/src/commonlib/include/commonlib/cbfs_serialized.h index 53b701ad71..e8f027fad3 100644 --- a/src/commonlib/include/commonlib/cbfs_serialized.h +++ b/src/commonlib/include/commonlib/cbfs_serialized.h @@ -68,6 +68,7 @@ #define CBFS_TYPE_DELETED2 0xffffffff #define CBFS_TYPE_STAGE 0x10 #define CBFS_TYPE_SELF 0x20 +#define CBFS_TYPE_FIT 0x21 #define CBFS_TYPE_OPTIONROM 0x30 #define CBFS_TYPE_BOOTSPLASH 0x40 #define CBFS_TYPE_RAW 0x50 diff --git a/util/cbfstool/cbfs-mkpayload.c b/util/cbfstool/cbfs-mkpayload.c index fd2c4ca011..6dc163433d 100644 --- a/util/cbfstool/cbfs-mkpayload.c +++ b/util/cbfstool/cbfs-mkpayload.c @@ -24,6 +24,7 @@ #include "cbfs.h" #include "fv.h" #include "coff.h" +#include "fdt.h" /* serialize the seg array into the buffer. * The buffer is assumed to be large enough. @@ -416,3 +417,39 @@ int parse_fv_to_payload(const struct buffer *input, struct buffer *output, return 0; } + +int parse_fit_to_payload(const struct buffer *input, struct buffer *output, + enum comp_algo algo) +{ + struct fdt_header *fdt_h; + + DEBUG("start: parse_fit_to_payload\n"); + + fdt_h = buffer_get(input); + if (be32toh(fdt_h->magic) != FDT_HEADER_MAGIC) { + INFO("Not a FIT payload.\n"); + return -1; + } + + /** + * For developers: + * Compress the kernel binary you're sourcing in your its-script + * manually with LZ4 or LZMA and add 'compression = "lz4"' or "lzma" to + * the kernel@1 node in the its-script before assembling the image with + * mkimage. + */ + if (algo != CBFS_COMPRESS_NONE) { + ERROR("FIT images don't support whole-image compression," + " compress the kernel component instead!\n") + return -1; + } + + if (buffer_create(output, buffer_size(input), input->name) != 0) + return -1; + + memcpy(buffer_get(output), buffer_get(input), buffer_size(input)); + + DEBUG("done\n"); + + return 0; +} diff --git a/util/cbfstool/cbfs.h b/util/cbfstool/cbfs.h index 1a4f101b57..fd2457a573 100644 --- a/util/cbfstool/cbfs.h +++ b/util/cbfstool/cbfs.h @@ -172,6 +172,7 @@ struct cbfs_payload { #define CBFS_COMPONENT_CBFSHEADER 0x02 #define CBFS_COMPONENT_STAGE 0x10 #define CBFS_COMPONENT_SELF 0x20 +#define CBFS_COMPONENT_FIT 0x21 #define CBFS_COMPONENT_OPTIONROM 0x30 #define CBFS_COMPONENT_BOOTSPLASH 0x40 #define CBFS_COMPONENT_RAW 0x50 @@ -205,6 +206,7 @@ static struct typedesc_t filetypes[] unused = { {CBFS_COMPONENT_CBFSHEADER, "cbfs header"}, {CBFS_COMPONENT_STAGE, "stage"}, {CBFS_COMPONENT_SELF, "simple elf"}, + {CBFS_COMPONENT_FIT, "fit"}, {CBFS_COMPONENT_OPTIONROM, "optionrom"}, {CBFS_COMPONENT_BOOTSPLASH, "bootsplash"}, {CBFS_COMPONENT_RAW, "raw"}, diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c index 08f2e32230..9b654b11b2 100644 --- a/util/cbfstool/cbfstool.c +++ b/util/cbfstool/cbfstool.c @@ -631,7 +631,14 @@ static int cbfstool_convert_mkpayload(struct buffer *buffer, /* per default, try and see if payload is an ELF binary */ ret = parse_elf_to_payload(buffer, &output, param.compression); - /* If it's not an ELF, see if it's a UEFI FV */ + /* If it's not an ELF, see if it's a FIT */ + if (ret != 0) { + ret = parse_fit_to_payload(buffer, &output, param.compression); + if (ret == 0) + header->type = htonl(CBFS_COMPONENT_FIT); + } + + /* If it's not an FIT, see if it's a UEFI FV */ if (ret != 0) ret = parse_fv_to_payload(buffer, &output, param.compression); diff --git a/util/cbfstool/common.h b/util/cbfstool/common.h index 8bae63e08e..baefc1cad0 100644 --- a/util/cbfstool/common.h +++ b/util/cbfstool/common.h @@ -188,6 +188,8 @@ int parse_elf_to_payload(const struct buffer *input, struct buffer *output, enum comp_algo algo); int parse_fv_to_payload(const struct buffer *input, struct buffer *output, enum comp_algo algo); +int parse_fit_to_payload(const struct buffer *input, struct buffer *output, + enum comp_algo algo); int parse_bzImage_to_payload(const struct buffer *input, struct buffer *output, const char *initrd, char *cmdline, enum comp_algo algo); diff --git a/util/cbfstool/fdt.h b/util/cbfstool/fdt.h new file mode 100644 index 0000000000..387cd328ed --- /dev/null +++ b/util/cbfstool/fdt.h @@ -0,0 +1,34 @@ +/* + * Copyright 2013 Google Inc. + * Copyright 2018-present Facebook, Inc. + * + * Taken from depthcharge: src/base/device_tree.h + * + * 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; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but without any warranty; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +struct fdt_header { + uint32_t magic; + uint32_t totalsize; + uint32_t structure_offset; + uint32_t strings_offset; + uint32_t reserve_map_offset; + + uint32_t version; + uint32_t last_compatible_version; + + uint32_t boot_cpuid_phys; + + uint32_t strings_size; + uint32_t structure_size; +}; + +#define FDT_HEADER_MAGIC 0xd00dfeed diff --git a/util/nvramtool/cbfs.h b/util/nvramtool/cbfs.h index 212aff96a6..b384ae9eac 100644 --- a/util/nvramtool/cbfs.h +++ b/util/nvramtool/cbfs.h @@ -68,6 +68,7 @@ typedef uint8_t u8; #define CBFS_TYPE_STAGE 0x10 #define CBFS_TYPE_SELF 0x20 +#define CBFS_TYPE_FIT 0x21 #define CBFS_TYPE_OPTIONROM 0x30 #define CBFS_TYPE_BOOTSPLASH 0x40 #define CBFS_TYPE_RAW 0x50 -- cgit v1.2.3