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 <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/25860
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
Patrick Rudolph 2018-04-26 09:35:13 +02:00 committed by Patrick Georgi
parent 31ff06a2da
commit 7ee05eddf1
9 changed files with 90 additions and 1 deletions

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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"},

View File

@ -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);

View File

@ -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);

34
util/cbfstool/fdt.h Normal file
View File

@ -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

View File

@ -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