summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDongjin Kim <tobetter@gmail.com>2020-03-28 13:55:19 +0900
committerDongjin Kim <tobetter@gmail.com>2020-03-28 23:56:10 +0900
commit25e589a2ae7f7dc01329a7431e651badcecf2e64 (patch)
tree138227c6459452ccf23cff93d6f3d4b3f9613edc
parent8c5681f3278858e505fd7308a9c577297930e24c (diff)
downloadu-boot-odroid-c1-25e589a2ae7f7dc01329a7431e651badcecf2e64.tar.gz
ODROID-C2: add buid package <fip_crate/amlbootsig> with bootstrap firmware
Change-Id: I4fd350871c0a55d6bb4faf5df059617673fcd50d Signed-off-by: Dongjin Kim <tobetter@gmail.com>
-rw-r--r--.gitignore11
-rw-r--r--Makefile5
-rw-r--r--board/hardkernel/odroid-c2/Makefile37
-rw-r--r--board/hardkernel/odroid-c2/bl1.bin.hardkernelbin0 -> 49664 bytes
-rwxr-xr-xboard/hardkernel/odroid-c2/fip/bl2_fix.sh11
-rwxr-xr-xboard/hardkernel/odroid-c2/fip/gxb/aml_encrypt_gxbbin0 -> 1011761 bytes
-rw-r--r--board/hardkernel/odroid-c2/fip/gxb/bl2.binbin0 -> 49152 bytes
-rwxr-xr-xboard/hardkernel/odroid-c2/fip/gxb/bl30.binbin0 -> 40584 bytes
-rwxr-xr-xboard/hardkernel/odroid-c2/fip/gxb/bl301.binbin0 -> 6228 bytes
-rwxr-xr-xboard/hardkernel/odroid-c2/fip/gxb/bl31.binbin0 -> 69840 bytes
-rw-r--r--board/hardkernel/odroid-c2/fip/gxb/u-boot.bin.usb.bl2bin0 -> 49151 bytes
-rw-r--r--board/hardkernel/odroid-c2/fip/gxb/u-boot.bin.usb.tplbin0 -> 622588 bytes
-rw-r--r--board/hardkernel/odroid-c2/fip/meson/u-boot.bin.usb.bl2bin0 -> 49151 bytes
-rw-r--r--board/hardkernel/odroid-c2/fip/meson/u-boot.bin.usb.tplbin0 -> 425983 bytes
-rw-r--r--board/hardkernel/odroid-c2/fip_create/Makefile39
-rw-r--r--board/hardkernel/odroid-c2/fip_create/fip_create.c678
-rw-r--r--board/hardkernel/odroid-c2/fip_create/fip_create.h61
-rw-r--r--board/hardkernel/odroid-c2/fip_create/firmware_image_package.h68
-rw-r--r--board/hardkernel/odroid-c2/fip_create/uuid.h61
-rw-r--r--board/hardkernel/odroid-c2/meson-tools/COPYING339
-rw-r--r--board/hardkernel/odroid-c2/meson-tools/Makefile14
-rw-r--r--board/hardkernel/odroid-c2/meson-tools/README.md76
-rw-r--r--board/hardkernel/odroid-c2/meson-tools/aml.h34
-rw-r--r--board/hardkernel/odroid-c2/meson-tools/amlbootsig.c263
-rw-r--r--board/hardkernel/odroid-c2/meson-tools/amlinfo.c103
-rw-r--r--board/hardkernel/odroid-c2/meson-tools/fip.h28
-rw-r--r--board/hardkernel/odroid-c2/meson-tools/meson.h21
-rw-r--r--board/hardkernel/odroid-c2/meson-tools/unamlbootsig.c141
-rwxr-xr-xboard/hardkernel/odroid-c2/sd_fusing.sh34
29 files changed, 2024 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 2e1c8bf2bf..ff45f0a546 100644
--- a/.gitignore
+++ b/.gitignore
@@ -92,3 +92,14 @@ GTAGS
*.orig
*~
\#*#
+
+# binaries built with odroid-c2_defconfig
+u-boot.bin.signed
+u-boot.bin.bundle
+u-boot.bin.fip
+u-boot.bin.usb.bl2
+u-boot.bin.usb.tpl
+fip_create
+amlbootsig
+amlinfo
+unamlbootsig
diff --git a/Makefile b/Makefile
index 34b46955f5..a13dcbdd87 100644
--- a/Makefile
+++ b/Makefile
@@ -773,6 +773,7 @@ libs-y += $(if $(BOARDDIR),board/$(BOARDDIR)/)
libs-y := $(sort $(libs-y))
u-boot-dirs := $(patsubst %/,%,$(filter %/, $(libs-y))) tools examples
+u-boot-dirs += board/hardkernel/odroid-c2/fip_create board/hardkernel/odroid-c2/meson-tools
u-boot-alldirs := $(sort $(u-boot-dirs) $(patsubst %/,%,$(filter %/, $(libs-))))
@@ -2173,3 +2174,7 @@ FORCE:
ifneq ($(CONFIG_TARGET_ODROID_XU3),)
include board/hardkernel/odroid-xu3/Makefile
endif
+
+ifeq ($(shell echo $(CONFIG_IDENT_STRING) | tr -d ' '),odroid-c2)
+include board/hardkernel/odroid-c2/Makefile
+endif
diff --git a/board/hardkernel/odroid-c2/Makefile b/board/hardkernel/odroid-c2/Makefile
new file mode 100644
index 0000000000..69071e9207
--- /dev/null
+++ b/board/hardkernel/odroid-c2/Makefile
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2020 Dongjin Kim <tobetter@gmail.com>
+#
+
+BOARD_DIR := $(srctree)/board/hardkernel/odroid-c2
+
+files = bl1.bin.hardkernel \
+ sd_fusing.sh
+
+targets = $(foreach blob, $(files), $(srctree)/sd_fuse/$(blob))
+
+$(targets):
+ $(Q)cp $(BOARD_DIR)/$(shell basename $@) \
+ $(shell dirname $@)
+
+prepare:
+ $(Q)mkdir -p $(srctree)/sd_fuse
+
+$(srctree)/sd_fuse/u-boot.bin: u-boot.bin
+ $(Q)$(BOARD_DIR)/fip_create/fip_create \
+ --bl30 $(BOARD_DIR)/fip/gxb/bl30.bin \
+ --bl301 $(BOARD_DIR)/fip/gxb/bl301.bin \
+ --bl31 $(BOARD_DIR)/fip/gxb/bl31.bin \
+ --bl33 u-boot.bin \
+ $(BOARD_DIR)/u-boot.bin.fip
+ $(Q)$(BOARD_DIR)/fip_create/fip_create --dump \
+ $(BOARD_DIR)/u-boot.bin.fip
+ $(Q)cat $(BOARD_DIR)/fip/gxb/bl2.bin \
+ $(BOARD_DIR)/u-boot.bin.fip \
+ > $(BOARD_DIR)/u-boot.bin.bundle
+ $(Q)$(BOARD_DIR)/meson-tools/amlbootsig \
+ $(BOARD_DIR)/u-boot.bin.bundle \
+ $(BOARD_DIR)/u-boot.bin.signed >/dev/null
+ $(Q)dd if=$(BOARD_DIR)/u-boot.bin.signed of=$@ bs=512 skip=96
+
+all: $(srctree)/sd_fuse/u-boot.bin $(targets)
diff --git a/board/hardkernel/odroid-c2/bl1.bin.hardkernel b/board/hardkernel/odroid-c2/bl1.bin.hardkernel
new file mode 100644
index 0000000000..571fc4677b
--- /dev/null
+++ b/board/hardkernel/odroid-c2/bl1.bin.hardkernel
Binary files differ
diff --git a/board/hardkernel/odroid-c2/fip/bl2_fix.sh b/board/hardkernel/odroid-c2/fip/bl2_fix.sh
new file mode 100755
index 0000000000..107d1ed6dc
--- /dev/null
+++ b/board/hardkernel/odroid-c2/fip/bl2_fix.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+declare -i bl2_size=`du -b $1 | awk '{print int($1)}'`
+
+declare -i zero_size=49152-$bl2_size
+
+dd if=/dev/zero of=$2 bs=1 count=$zero_size
+
+cat $1 $2 > $3
+
+rm $2
diff --git a/board/hardkernel/odroid-c2/fip/gxb/aml_encrypt_gxb b/board/hardkernel/odroid-c2/fip/gxb/aml_encrypt_gxb
new file mode 100755
index 0000000000..8ac4738411
--- /dev/null
+++ b/board/hardkernel/odroid-c2/fip/gxb/aml_encrypt_gxb
Binary files differ
diff --git a/board/hardkernel/odroid-c2/fip/gxb/bl2.bin b/board/hardkernel/odroid-c2/fip/gxb/bl2.bin
new file mode 100644
index 0000000000..23925f44f8
--- /dev/null
+++ b/board/hardkernel/odroid-c2/fip/gxb/bl2.bin
Binary files differ
diff --git a/board/hardkernel/odroid-c2/fip/gxb/bl30.bin b/board/hardkernel/odroid-c2/fip/gxb/bl30.bin
new file mode 100755
index 0000000000..353a9dba17
--- /dev/null
+++ b/board/hardkernel/odroid-c2/fip/gxb/bl30.bin
Binary files differ
diff --git a/board/hardkernel/odroid-c2/fip/gxb/bl301.bin b/board/hardkernel/odroid-c2/fip/gxb/bl301.bin
new file mode 100755
index 0000000000..b6ca8f795a
--- /dev/null
+++ b/board/hardkernel/odroid-c2/fip/gxb/bl301.bin
Binary files differ
diff --git a/board/hardkernel/odroid-c2/fip/gxb/bl31.bin b/board/hardkernel/odroid-c2/fip/gxb/bl31.bin
new file mode 100755
index 0000000000..3e9d82d3e1
--- /dev/null
+++ b/board/hardkernel/odroid-c2/fip/gxb/bl31.bin
Binary files differ
diff --git a/board/hardkernel/odroid-c2/fip/gxb/u-boot.bin.usb.bl2 b/board/hardkernel/odroid-c2/fip/gxb/u-boot.bin.usb.bl2
new file mode 100644
index 0000000000..56af908012
--- /dev/null
+++ b/board/hardkernel/odroid-c2/fip/gxb/u-boot.bin.usb.bl2
Binary files differ
diff --git a/board/hardkernel/odroid-c2/fip/gxb/u-boot.bin.usb.tpl b/board/hardkernel/odroid-c2/fip/gxb/u-boot.bin.usb.tpl
new file mode 100644
index 0000000000..d7ace0229c
--- /dev/null
+++ b/board/hardkernel/odroid-c2/fip/gxb/u-boot.bin.usb.tpl
Binary files differ
diff --git a/board/hardkernel/odroid-c2/fip/meson/u-boot.bin.usb.bl2 b/board/hardkernel/odroid-c2/fip/meson/u-boot.bin.usb.bl2
new file mode 100644
index 0000000000..2aa58b560c
--- /dev/null
+++ b/board/hardkernel/odroid-c2/fip/meson/u-boot.bin.usb.bl2
Binary files differ
diff --git a/board/hardkernel/odroid-c2/fip/meson/u-boot.bin.usb.tpl b/board/hardkernel/odroid-c2/fip/meson/u-boot.bin.usb.tpl
new file mode 100644
index 0000000000..200f215a99
--- /dev/null
+++ b/board/hardkernel/odroid-c2/fip/meson/u-boot.bin.usb.tpl
Binary files differ
diff --git a/board/hardkernel/odroid-c2/fip_create/Makefile b/board/hardkernel/odroid-c2/fip_create/Makefile
new file mode 100644
index 0000000000..0aa3446806
--- /dev/null
+++ b/board/hardkernel/odroid-c2/fip_create/Makefile
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+hostprogs-y := fip_create
+
+HOSTCFLAGS_fip_create.o := \
+ -I$(srctree)/board/hardkernel/odroid-c2/fip_create \
+ -O2 -Wall -pedantic -std=c99 -DXXX
+
+fip_create-objs := fip_create.o
+
+always := $(hostprogs-y)
diff --git a/board/hardkernel/odroid-c2/fip_create/fip_create.c b/board/hardkernel/odroid-c2/fip_create/fip_create.c
new file mode 100644
index 0000000000..255fab9c71
--- /dev/null
+++ b/board/hardkernel/odroid-c2/fip_create/fip_create.c
@@ -0,0 +1,678 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/types.h>
+#include <errno.h>
+#include <getopt.h> /* getopt_long() is a GNU extention */
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include "fip_create.h"
+#include "firmware_image_package.h"
+
+/* Values returned by getopt() as part of the command line parsing */
+#define OPT_TOC_ENTRY 0
+#define OPT_DUMP 1
+#define OPT_HELP 2
+
+file_info_t files[MAX_FILES];
+unsigned file_info_count = 0;
+uuid_t uuid_null = {0};
+
+/*
+ * TODO: Add ability to specify and flag different file types.
+ * Add flags to the toc_entry?
+ * const char* format_type_str[] = { "RAW", "ELF", "PIC" };
+ */
+
+/* The images used depends on the platform. */
+static entry_lookup_list_t toc_entry_lookup_list[] = {
+ { "Trusted Boot Firmware BL2", UUID_TRUSTED_BOOT_FIRMWARE_BL2,
+ "bl2", NULL, FLAG_FILENAME },
+ { "SCP Firmware BL3-0", UUID_SCP_FIRMWARE_BL30,
+ "bl30", NULL, FLAG_FILENAME},
+ { "SCP Firmware BL3-0-1", UUID_SCP_FIRMWARE_BL301,
+ "bl301", NULL, FLAG_FILENAME},
+ { "EL3 Runtime Firmware BL3-1", UUID_EL3_RUNTIME_FIRMWARE_BL31,
+ "bl31", NULL, FLAG_FILENAME},
+ { "Secure Payload BL3-2 (Trusted OS)", UUID_SECURE_PAYLOAD_BL32,
+ "bl32", NULL, FLAG_FILENAME},
+ { "Non-Trusted Firmware BL3-3", UUID_NON_TRUSTED_FIRMWARE_BL33,
+ "bl33", NULL, FLAG_FILENAME},
+ { NULL, {0}, 0 }
+};
+
+
+/* Return 0 for equal uuids */
+static inline int compare_uuids(const uuid_t *uuid1, const uuid_t *uuid2)
+{
+ return memcmp(uuid1, uuid2, sizeof(uuid_t));
+}
+
+
+static inline void copy_uuid(uuid_t *to_uuid, const uuid_t *from_uuid)
+{
+ memcpy(to_uuid, from_uuid, sizeof(uuid_t));
+}
+
+
+static void print_usage(void)
+{
+ entry_lookup_list_t *entry = toc_entry_lookup_list;
+
+ printf("Usage: fip_create [options] FIP_FILENAME\n\n");
+ printf("\tThis tool is used to create a Firmware Image Package.\n\n");
+ printf("Options:\n");
+ printf("\t--help: Print this help message and exit\n");
+ printf("\t--dump: Print contents of FIP\n\n");
+ printf("\tComponents that can be added/updated:\n");
+ for (; entry->command_line_name != NULL; entry++) {
+ printf("\t--%s%s\t\t%s",
+ entry->command_line_name,
+ (entry->flags & FLAG_FILENAME) ? " FILENAME" : "",
+ entry->name);
+ printf("\n");
+ }
+}
+
+
+static entry_lookup_list_t *get_entry_lookup_from_uuid(const uuid_t *uuid)
+{
+ unsigned int lookup_index = 0;
+
+ while (toc_entry_lookup_list[lookup_index].command_line_name != NULL) {
+ if (compare_uuids(&toc_entry_lookup_list[lookup_index].name_uuid,
+ uuid) == 0) {
+ return &toc_entry_lookup_list[lookup_index];
+ }
+ lookup_index++;
+ }
+ return NULL;
+}
+
+
+static file_info_t *find_file_info_from_uuid(const uuid_t *uuid)
+{
+ int index;
+
+ for (index = 0; index < file_info_count; index++) {
+ if (compare_uuids(&files[index].name_uuid, uuid) == 0) {
+ return &files[index];
+ }
+ }
+ return NULL;
+}
+
+
+static int add_file_info_entry(entry_lookup_list_t *lookup_entry, char *filename)
+{
+ file_info_t *file_info_entry;
+ int error;
+ struct stat file_status;
+ bool is_new_entry = false;
+
+ /* Check if the file already exists in the array */
+ file_info_entry = find_file_info_from_uuid(&lookup_entry->name_uuid);
+ if (file_info_entry == NULL) {
+ /* The file does not exist in the current list; take the next
+ * one available in the file_info list. 'file_info_count' is
+ * incremented in case of successful update at the end of the
+ * function.
+ */
+ file_info_entry = &files[file_info_count];
+ is_new_entry = true;
+
+ /* Copy the uuid for the new entry */
+ copy_uuid(&file_info_entry->name_uuid,
+ &lookup_entry->name_uuid);
+ }
+
+ /* Get the file information for entry */
+ error = stat(filename, &file_status);
+ if (error != 0) {
+ printf("Error: Cannot get information for file \"%s\": %s\n",
+ filename, strerror(errno));
+ return errno;
+ }
+ file_info_entry->filename = filename;
+ file_info_entry->size = (unsigned int)file_status.st_size;
+ file_info_entry->align_size = 0x4000 * ((file_info_entry->size / 0x4000) + 1);
+ file_info_entry->entry = lookup_entry;
+
+ /* Increment the file_info counter on success if it is new file entry */
+ if (is_new_entry) {
+ file_info_count++;
+
+ /* Ensure we do not overflow */
+ if (file_info_count > MAX_FILES) {
+ printf("ERROR: Too many files in Package\n");
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+static int write_memory_to_file(const uint8_t *start, const char *filename,
+ unsigned int size)
+{
+ FILE *stream;
+ unsigned int bytes_written;
+
+ /* Write the packed file out to the filesystem */
+ stream = fopen(filename, "r+");
+ if (stream == NULL) {
+ stream = fopen(filename, "w");
+ if (stream == NULL) {
+ printf("Error: Cannot create output file \"%s\": %s\n",
+ filename, strerror(errno));
+ return errno;
+ } else {
+ printf("Creating \"%s\"\n", filename);
+ }
+ } else {
+ printf("Updating \"%s\"\n", filename);
+ }
+
+ bytes_written = fwrite(start, sizeof(uint8_t), size, stream);
+ fclose(stream);
+
+ if (bytes_written != size) {
+ printf("Error: Incorrect write for file \"%s\": Size=%u,"
+ "Written=%u bytes.\n", filename, size, bytes_written);
+ return EIO;
+ }
+
+ return 0;
+}
+
+
+static int read_file_to_memory(void *memory, const file_info_t *info)
+{
+ FILE *stream;
+ unsigned int bytes_read;
+
+ /* If the file_info is defined by its filename we need to load it */
+ if (info->filename) {
+ /* Read image from filesystem */
+ stream = fopen(info->filename, "r");
+ if (stream == NULL) {
+ printf("Error: Cannot open file \"%s\": %s\n",
+ info->filename, strerror(errno));
+ return errno;
+ }
+
+ bytes_read = (unsigned int)fread(memory, sizeof(uint8_t),
+ info->size, stream);
+ fclose(stream);
+ if (bytes_read != info->size) {
+ printf("Error: Incomplete read for file \"%s\":"
+ "Size=%u, Read=%u bytes.\n", info->filename,
+ info->size, bytes_read);
+ return EIO;
+ }
+ } else {
+ if (info->image_buffer == NULL) {
+ printf("ERROR: info->image_buffer = NULL\n");
+ return EIO;
+ }
+ /* Copy the file_info buffer (extracted from the existing
+ * image package) into the new buffer.
+ */
+ memcpy(memory, info->image_buffer, info->size);
+ }
+
+ return 0;
+}
+
+
+/* Create the image package file */
+static int pack_images(const char *fip_filename)
+{
+ int status;
+ uint8_t *fip_base_address;
+ void *entry_address;
+ fip_toc_header_t *toc_header;
+ fip_toc_entry_t *toc_entry;
+ unsigned int entry_index;
+ unsigned int toc_size;
+ unsigned int fip_size;
+ unsigned int entry_offset_address;
+ unsigned int payload_size = 0;
+
+ /* Validate filename */
+ if ((fip_filename == NULL) || (strcmp(fip_filename, "") == 0)) {
+ return EINVAL;
+ }
+
+ /* Payload size calculation */
+ for (entry_index = 0; entry_index < file_info_count; entry_index++) {
+ payload_size += files[entry_index].align_size;
+ }
+
+ /* Allocate memory for entire package, including the final null entry */
+ //toc_size = (sizeof(fip_toc_header_t) +
+ //(sizeof(fip_toc_entry_t) * (file_info_count + 1)));
+ toc_size = 0x4000;
+ fip_size = toc_size + payload_size;
+ fip_base_address = malloc(fip_size);
+ if (fip_base_address == NULL) {
+ printf("Error: Can't allocate enough memory to create package."
+ "Process aborted.\n");
+ return ENOMEM;
+ }
+ memset(fip_base_address, 0, fip_size);
+
+ /* Create ToC Header */
+ toc_header = (fip_toc_header_t *)fip_base_address;
+ toc_header->name = TOC_HEADER_NAME;
+ toc_header->serial_number = TOC_HEADER_SERIAL_NUMBER;
+ toc_header->flags = 0;
+
+ toc_entry = (fip_toc_entry_t *)(fip_base_address +
+ sizeof(fip_toc_header_t));
+
+ /* Calculate the starting address of the first image, right after the
+ * toc header.
+ */
+ entry_offset_address = toc_size;
+ entry_index = 0;
+
+ /* Create the package in memory. */
+ for (entry_index = 0; entry_index < file_info_count; entry_index++) {
+ entry_address = (fip_base_address + entry_offset_address);
+ status = read_file_to_memory(entry_address,
+ &files[entry_index]);
+ if (status != 0) {
+ printf("Error: While reading \"%s\" from filesystem.\n",
+ files[entry_index].filename);
+ return status;
+ }
+
+ copy_uuid(&toc_entry->uuid, &files[entry_index].name_uuid);
+ toc_entry->offset_address = entry_offset_address;
+ toc_entry->size = files[entry_index].size;
+ toc_entry->flags = 0;
+ entry_offset_address += files[entry_index].align_size;
+ toc_entry++;
+ }
+
+ /* Add a null uuid entry to mark the end of toc entries */
+ copy_uuid(&toc_entry->uuid, &uuid_null);
+ toc_entry->offset_address = entry_offset_address;
+ toc_entry->size = 0;
+ toc_entry->flags = 0;
+
+ /* Save the package to file */
+ status = write_memory_to_file(fip_base_address, fip_filename, fip_size);
+ if (status != 0) {
+ printf("Error: Failed while writing package to file \"%s\" "
+ "with status=%d.\n", fip_filename, status);
+ return status;
+ }
+ return 0;
+}
+
+
+static void dump_toc(void)
+{
+ unsigned int index = 0;
+ unsigned int image_offset;
+ unsigned int image_size = 0;
+
+ //image_offset = sizeof(fip_toc_header_t) +
+ //(sizeof(fip_toc_entry_t) * (file_info_count + 1));
+ image_offset = 0x4000;
+
+ printf("Firmware Image Package ToC:\n");
+ printf("---------------------------\n");
+ for (index = 0; index < file_info_count; index++) {
+ if (files[index].entry) {
+ printf("- %s: ", files[index].entry->name);
+ } else {
+ printf("- Unknown entry: ");
+ }
+ image_size = files[index].size;
+
+ printf("offset=0x%X, size=0x%X\n", image_offset, image_size);
+ image_offset += files[index].align_size;
+
+ if (files[index].filename) {
+ printf(" file: '%s'\n", files[index].filename);
+ }
+ }
+ printf("---------------------------\n");
+}
+
+
+/* Read and load existing package into memory. */
+static int parse_fip(const char *fip_filename)
+{
+ FILE *fip;
+ char *fip_buffer;
+ char *fip_buffer_end;
+ int fip_size, read_fip_size;
+ fip_toc_header_t *toc_header;
+ fip_toc_entry_t *toc_entry;
+ bool found_last_toc_entry = false;
+ file_info_t *file_info_entry;
+ int status = -1;
+ struct stat st;
+
+ fip = fopen(fip_filename, "r");
+ if (fip == NULL) {
+ /* If the fip does not exist just return, it should not be
+ * considered as an error. The package will be created later
+ */
+ status = 0;
+ goto parse_fip_return;
+ }
+
+ if (stat(fip_filename, &st) != 0) {
+ status = errno;
+ goto parse_fip_fclose;
+ } else {
+ fip_size = (int)st.st_size;
+ }
+
+ /* Allocate a buffer to read the package */
+ fip_buffer = (char *)malloc(fip_size);
+ if (fip_buffer == NULL) {
+ printf("ERROR: Cannot allocate %d bytes.\n", fip_size);
+ status = errno;
+ goto parse_fip_fclose;
+ }
+ fip_buffer_end = fip_buffer + fip_size;
+
+ /* Read the file */
+ read_fip_size = fread(fip_buffer, sizeof(char), fip_size, fip);
+ if (read_fip_size != fip_size) {
+ printf("ERROR: Cannot read the FIP.\n");
+ status = EIO;
+ goto parse_fip_free;
+ }
+ fclose(fip);
+ fip = NULL;
+
+ /* The package must at least contain the ToC Header */
+ if (fip_size < sizeof(fip_toc_header_t)) {
+ printf("ERROR: Given FIP is smaller than the ToC header.\n");
+ status = EINVAL;
+ goto parse_fip_free;
+ }
+ /* Set the ToC Header at the base of the buffer */
+ toc_header = (fip_toc_header_t *)fip_buffer;
+ /* The first toc entry should be just after the ToC header */
+ toc_entry = (fip_toc_entry_t *)(toc_header + 1);
+
+ /* While the ToC entry is contained into the buffer */
+ int cnt = 0;
+ while (((char *)toc_entry + sizeof(fip_toc_entry_t)) < fip_buffer_end) {
+ cnt++;
+ /* Check if the ToC Entry is the last one */
+ if (compare_uuids(&toc_entry->uuid, &uuid_null) == 0) {
+ found_last_toc_entry = true;
+ status = 0;
+ break;
+ }
+
+ /* Add the entry into file_info */
+
+ /* Get the new entry in the array and clear it */
+ file_info_entry = &files[file_info_count++];
+ memset(file_info_entry, 0, sizeof(file_info_t));
+
+ /* Copy the info from the ToC entry */
+ copy_uuid(&file_info_entry->name_uuid, &toc_entry->uuid);
+ file_info_entry->image_buffer = fip_buffer +
+ toc_entry->offset_address;
+ file_info_entry->size = toc_entry->size;
+ file_info_entry->align_size = 0x4000 * ((toc_entry->size / 0x4000) + 1);
+
+ /* Check if there is a corresponding entry in lookup table */
+ file_info_entry->entry =
+ get_entry_lookup_from_uuid(&toc_entry->uuid);
+
+ /* Go to the next ToC entry */
+ toc_entry++;
+ }
+
+ if (!found_last_toc_entry) {
+ printf("ERROR: Given FIP does not have an end ToC entry.\n");
+ status = EINVAL;
+ goto parse_fip_free;
+ } else {
+ /* All is well, we should not free any of the loaded images */
+ goto parse_fip_fclose;
+ }
+
+ parse_fip_free:
+ if (fip_buffer != NULL) {
+ free(fip_buffer);
+ fip_buffer = NULL;
+ }
+
+ parse_fip_fclose:
+ if (fip != NULL) {
+ fclose(fip);
+ }
+
+ parse_fip_return:
+ return status;
+}
+
+
+/* Parse all command-line options and return the FIP name if present. */
+static char *get_filename(int argc, char **argv, struct option *options)
+{
+ int c;
+ char *filename = NULL;
+
+ /* Reset option pointer so we parse all args. starts at 1.
+ * The filename is the only argument that does not have an option flag.
+ */
+ optind = 1;
+ while (1) {
+ c = getopt_long(argc, argv, "", options, NULL);
+ if (c == -1)
+ break;
+
+ if (c == '?') {
+ /* Failed to parse an option. Fail. */
+ return NULL;
+ }
+ }
+
+ /* Only one argument left then it is the filename.
+ * We dont expect any other options
+ */
+ if (optind + 1 == argc)
+ filename = argv[optind];
+
+ return filename;
+}
+
+
+/* Work through command-line options */
+static int parse_cmdline(int argc, char **argv, struct option *options,
+ int *do_pack)
+{
+ int c;
+ int status = 0;
+ int option_index = 0;
+ entry_lookup_list_t *lookup_entry;
+ int do_dump = 0;
+
+ /* restart parse to process all options. starts at 1. */
+ optind = 1;
+ while (1) {
+ c = getopt_long(argc, argv, "", options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case OPT_TOC_ENTRY:
+ if (optarg) {
+ /* Does the option expect a filename. */
+ lookup_entry = &toc_entry_lookup_list[option_index];
+ if (lookup_entry->flags & FLAG_FILENAME) {
+ status = add_file_info_entry(lookup_entry, optarg);
+ if (status != 0) {
+ printf("Failed to process %s\n",
+ options[option_index].name);
+ break;
+ } else {
+ /* Update package */
+ *do_pack = 1;
+ }
+ }
+ }
+ break;
+
+ case OPT_DUMP:
+ do_dump = 1;
+ continue;
+
+ case OPT_HELP:
+ print_usage();
+ exit(0);
+
+ default:
+ /* Unrecognised options are caught in get_filename() */
+ break;
+ }
+ }
+
+
+ /* Do not dump toc if we have an error as it could hide the error */
+ if ((status == 0) && (do_dump)) {
+ dump_toc();
+ }
+
+ return status;
+
+}
+
+int main(int argc, char **argv)
+{
+ int i;
+ int status;
+ char *fip_filename;
+ int do_pack = 0;
+
+ /* Clear file list table. */
+ memset(files, 0, sizeof(files));
+
+ /* Initialise for getopt_long().
+ * Use image table as defined at top of file to get options.
+ * Add 'dump' option, 'help' option and end marker.
+ */
+ static struct option long_options[(sizeof(toc_entry_lookup_list)/
+ sizeof(entry_lookup_list_t)) + 2];
+
+ for (i = 0;
+ /* -1 because we dont want to process end marker in toc table */
+ i < sizeof(toc_entry_lookup_list)/sizeof(entry_lookup_list_t) - 1;
+ i++) {
+ long_options[i].name = toc_entry_lookup_list[i].command_line_name;
+ /* The only flag defined at the moment is for a FILENAME */
+ long_options[i].has_arg = toc_entry_lookup_list[i].flags ? 1 : 0;
+ long_options[i].flag = 0;
+ long_options[i].val = OPT_TOC_ENTRY;
+ }
+
+ /* Add '--dump' option */
+ long_options[i].name = "dump";
+ long_options[i].has_arg = 0;
+ long_options[i].flag = 0;
+ long_options[i].val = OPT_DUMP;
+
+ /* Add '--help' option */
+ long_options[++i].name = "help";
+ long_options[i].has_arg = 0;
+ long_options[i].flag = 0;
+ long_options[i].val = OPT_HELP;
+
+ /* Zero the last entry (required) */
+ long_options[++i].name = 0;
+ long_options[i].has_arg = 0;
+ long_options[i].flag = 0;
+ long_options[i].val = 0;
+
+#ifdef DEBUG
+ /* Print all supported options */
+ for (i = 0; i < sizeof(long_options)/sizeof(struct option); i++) {
+ printf("long opt (%d) : name = %s\n", i, long_options[i].name);
+ }
+#endif /* DEBUG */
+
+ /* As the package may already exist and is to be updated we need to get
+ * the filename from the arguments and load from it.
+ * NOTE: As this is the first function to look at the program arguments
+ * it causes a failure if bad options were provided.
+ */
+ fip_filename = get_filename(argc, argv, long_options);
+
+ /* Try to open the file and load it into memory */
+ if (fip_filename != NULL) {
+ status = parse_fip(fip_filename);
+ if (status != 0) {
+ return status;
+ }
+ }
+
+ /* Work through provided program arguments and perform actions */
+ status = parse_cmdline(argc, argv, long_options, &do_pack);
+ if (status != 0) {
+ return status;
+ };
+
+ if (fip_filename == NULL) {
+ printf("ERROR: Missing FIP filename\n");
+ print_usage();
+ return 0;
+ }
+
+ /* Processed all command line options. Create/update the package if
+ * required.
+ */
+ if (do_pack) {
+ status = pack_images(fip_filename);
+ if (status != 0) {
+ printf("Failed to create package (status = %d).\n",
+ status);
+ }
+ }
+
+ return status;
+}
diff --git a/board/hardkernel/odroid-c2/fip_create/fip_create.h b/board/hardkernel/odroid-c2/fip_create/fip_create.h
new file mode 100644
index 0000000000..81e0897f98
--- /dev/null
+++ b/board/hardkernel/odroid-c2/fip_create/fip_create.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __FIP_CREATE_H__
+#define __FIP_CREATE_H__
+
+#include <stdint.h>
+#include <uuid.h>
+
+#define MAX_FILES 10
+
+/* TODO: Update this number as required */
+#define TOC_HEADER_SERIAL_NUMBER 0x12345678
+
+#define FLAG_FILENAME (1 << 0)
+
+typedef struct entry_lookup_list {
+ const char *name;
+ uuid_t name_uuid;
+ const char *command_line_name;
+ struct file_info *info;
+ unsigned int flags;
+} entry_lookup_list_t;
+
+typedef struct file_info {
+ uuid_t name_uuid;
+ const char *filename;
+ unsigned int size;
+ unsigned int align_size;
+ void *image_buffer;
+ entry_lookup_list_t *entry;
+} file_info_t;
+
+#endif /* __FIP_CREATE_H__ */
diff --git a/board/hardkernel/odroid-c2/fip_create/firmware_image_package.h b/board/hardkernel/odroid-c2/fip_create/firmware_image_package.h
new file mode 100644
index 0000000000..0a8a67d9ac
--- /dev/null
+++ b/board/hardkernel/odroid-c2/fip_create/firmware_image_package.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __FIRMWARE_IMAGE_PACKAGE_H__
+#define __FIRMWARE_IMAGE_PACKAGE_H__
+
+#include <stdint.h>
+#include <uuid.h>
+
+/* This is used as a signature to validate the blob header */
+#define TOC_HEADER_NAME 0xAA640001
+
+
+/* ToC Entry UUIDs */
+#define UUID_TRUSTED_BOOT_FIRMWARE_BL2 \
+ {0x0becf95f, 0x224d, 0x4d3e, 0xa5, 0x44, {0xc3, 0x9d, 0x81, 0xc7, 0x3f, 0x0a} }
+#define UUID_SCP_FIRMWARE_BL30 \
+ {0x3dfd6697, 0xbe89, 0x49e8, 0xae, 0x5d, {0x78, 0xa1, 0x40, 0x60, 0x82, 0x13} }
+#define UUID_SCP_FIRMWARE_BL301 \
+ {0xAABBCCDD, 0xABCD, 0xEFEF, 0xAB, 0xCD, {0x12, 0x34, 0x56, 0x78, 0xAB, 0xCD} }
+#define UUID_EL3_RUNTIME_FIRMWARE_BL31 \
+ {0x6d08d447, 0xfe4c, 0x4698, 0x9b, 0x95, {0x29, 0x50, 0xcb, 0xbd, 0x5a, 0x00} }
+#define UUID_SECURE_PAYLOAD_BL32 \
+ {0x89e1d005, 0xdc53, 0x4713, 0x8d, 0x2b, {0x50, 0x0a, 0x4b, 0x7a, 0x3e, 0x38} }
+#define UUID_NON_TRUSTED_FIRMWARE_BL33 \
+ {0xa7eed0d6, 0xeafc, 0x4bd5, 0x97, 0x82, {0x99, 0x34, 0xf2, 0x34, 0xb6, 0xe4} }
+
+typedef struct fip_toc_header {
+ uint32_t name;
+ uint32_t serial_number;
+ uint64_t flags;
+} fip_toc_header_t;
+
+typedef struct fip_toc_entry {
+ uuid_t uuid;
+ uint64_t offset_address;
+ uint64_t size;
+ uint64_t flags;
+} fip_toc_entry_t;
+
+#endif /* __FIRMWARE_IMAGE_PACKAGE_H__ */
diff --git a/board/hardkernel/odroid-c2/fip_create/uuid.h b/board/hardkernel/odroid-c2/fip_create/uuid.h
new file mode 100644
index 0000000000..5c4767b5b5
--- /dev/null
+++ b/board/hardkernel/odroid-c2/fip_create/uuid.h
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 2002 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Portions copyright (c) 2014, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef _SYS_UUID_H_
+#define _SYS_UUID_H_
+
+#include <sys/cdefs.h>
+
+/* Length of a node address (an IEEE 802 address). */
+#define _UUID_NODE_LEN 6
+
+/*
+ * See also:
+ * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
+ * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm
+ *
+ * A DCE 1.1 compatible source representation of UUIDs.
+ */
+struct uuid {
+ uint32_t time_low;
+ uint16_t time_mid;
+ uint16_t time_hi_and_version;
+ uint8_t clock_seq_hi_and_reserved;
+ uint8_t clock_seq_low;
+ uint8_t node[_UUID_NODE_LEN];
+};
+
+/* XXX namespace pollution? */
+typedef struct uuid uuid_t;
+
+#endif /* _SYS_UUID_H_ */
diff --git a/board/hardkernel/odroid-c2/meson-tools/COPYING b/board/hardkernel/odroid-c2/meson-tools/COPYING
new file mode 100644
index 0000000000..d159169d10
--- /dev/null
+++ b/board/hardkernel/odroid-c2/meson-tools/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/board/hardkernel/odroid-c2/meson-tools/Makefile b/board/hardkernel/odroid-c2/meson-tools/Makefile
new file mode 100644
index 0000000000..758729de1c
--- /dev/null
+++ b/board/hardkernel/odroid-c2/meson-tools/Makefile
@@ -0,0 +1,14 @@
+hostprogs-y := amlbootsig unamlbootsig amlinfo
+always := $(hostprogs-y)
+
+COMMON_CFLAGS := -g -I/usr/include/openssl
+
+HOSTCFLAGS_amlbootsig.o := $(COMMON_CFLAGS)
+HOSTLOADLIBES_amlbootsig = -lcrypto
+amlbootsig-objs := amlbootsig.o
+
+HOSTCFLAGS_unamlbootsig.o := $(COMMON_CFLAGS)
+unamlbootsig-objs := unamlbootsig.o
+
+HOSTCFLAGS_amlinfo.o := $(COMMON_CFLAGS)
+amlinfo-objs := amlinfo.o
diff --git a/board/hardkernel/odroid-c2/meson-tools/README.md b/board/hardkernel/odroid-c2/meson-tools/README.md
new file mode 100644
index 0000000000..bdb1f83e1c
--- /dev/null
+++ b/board/hardkernel/odroid-c2/meson-tools/README.md
@@ -0,0 +1,76 @@
+# meson-tools
+
+meson-tools is a collection of tools for use with the Amlogic Meson family of ARM based SoCs.
+
+Name-wise it was inspired by [sunxi-tools](https://github.com/linux-sunxi/sunxi-tools/).
+
+## amlbootsig
+
+Usage:
+```
+ amlbootsig boot_new.bin u-boot.img
+```
+
+This tool is supposed to provide equivalent output to:
+```
+ aml_encrypt_gxb --bootsig --input boot_new.bin --output u-boot.img
+```
+with the tool version distributed by Hardkernel for their Odroid-C2 board (S905 / Meson GXBaby).
+
+### How to compare output
+
+```
+ hexdump -C a/u-boot.img > a/u-boot.img.hex
+ hexdump -C b/u-boot.img > b/u-boot.img.hex
+ diff -u a/u-boot.img.hex b/u-boot.img.hex | less
+```
+
+This should result in a diff with only the following differences:
+
+* First 16 bytes will be random in original.
+* The header for each FIP TOC entry will contain 4 bytes of random data.
+* Due to FIP TOC entry headers differing, the SHA256 hash in the header will differ as well.
+
+For testing identity of output files, modify the code to use the random bytes from the file you are testing against.
+
+### Known limitations
+
+* Correctness: Since amlbootsig was designed to binary-match previously created output files, it may still have some numbers hard-coded or may do calculations in a way that happened to match tested input/output but may break for other input files. Please report such cases as GitHub issues.
+* Endianness: Only Little Endian byte order has been considered. Running it on Big Endian hosts may misinterpret file input and/or result in wrong output and/or other misbehavior. The solution would be byte swaps, but those depend on the field width, which is guessed only and thus may change as the format is being better understood.
+* Security: The tool was not designed to defend against invalid or evil file input.
+
+## unamlbootsig
+
+Usage:
+```
+unamlbootsig u-boot.img boot_new.bin
+```
+
+This tool is supposed to do the reverse of `amlbootsig`, i.e. drop the boot signature.
+
+The output may differ from the original `aml_encrypt_gxb --bootsig`/`amlbootsig` input from 0xb000 to 0xbfff as well as in FIP TOC entry size 16-byte alignment.
+
+### Known limitations
+
+See `amlbootsig`.
+
+## amlinfo
+
+Usage:
+```
+ amlinfo u-boot.img
+```
+
+This tool dumps info about an existing image file.
+
+It supports the following inputs:
+* `amlbootsig` output
+* `aml_encrypt_gxb --bootsig` output, except when using `--amluserkey` or `--efuse`
+* `dd if=u-boot.img bs=512 skip=96` output for either of them (FIP TOC with headered entries)
+* `dd if=u-boot.img bs=1 skip=16` output, i.e. raw `@AML` header, of at least 64 bytes
+
+### Known limitations
+
+* Correctness: Since there seems to be no public documentation for the @AML headers, any field names printed are guesses and may need to be revised once their meaning becauses clearer.
+* Endianness: Only Little Endian byte order has been considered, see above.
+* Security: See above.
diff --git a/board/hardkernel/odroid-c2/meson-tools/aml.h b/board/hardkernel/odroid-c2/meson-tools/aml.h
new file mode 100644
index 0000000000..0a21f373ce
--- /dev/null
+++ b/board/hardkernel/odroid-c2/meson-tools/aml.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017 Andreas Färber
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR MIT
+ */
+
+#ifndef AML_H
+#define AML_H
+
+#include <stdint.h>
+
+#define AMLOGIC_SIGNATURE "@AML"
+
+struct __attribute((__packed__)) AmlogicHeader {
+ char sig[4];
+ uint32_t size;
+ uint16_t header_size;
+ uint16_t header_version;
+ uint32_t id;
+ uint32_t encrypted;
+ uint32_t digest_offset;
+ uint32_t digest_size;
+ uint32_t data_offset;
+ uint32_t data_size;
+ uint32_t padding_offset;
+ uint32_t padding_size;
+ uint32_t _offset2;
+ uint32_t pad2;
+ uint32_t payload_offset;
+ uint32_t payload_size;
+ uint32_t unknown;
+};
+
+#endif
diff --git a/board/hardkernel/odroid-c2/meson-tools/amlbootsig.c b/board/hardkernel/odroid-c2/meson-tools/amlbootsig.c
new file mode 100644
index 0000000000..4d00548bc5
--- /dev/null
+++ b/board/hardkernel/odroid-c2/meson-tools/amlbootsig.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2017 Andreas Färber
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/sha.h>
+
+#include "meson.h"
+
+/*
+ * COMPARE_MODE: Define this and change values below to match files
+ * generated by aml_encrypt_gxb.
+ */
+#undef COMPARE_MODE
+
+#ifndef COMPARE_MODE
+/*
+ * REPRODUCIBLE_OUTPUT: For the benefit of generating reproducible packages,
+ * deviate from aml_encrypt_gxb in not using random / time-based values.
+ */
+#define REPRODUCIBLE_OUTPUT
+#endif
+
+static int do_fip(FILE *fout, FILE *fin)
+{
+ char *toc_buf, *buf;
+ struct FipHeader *ptoc;
+ int i, n;
+ long toc_pos;
+
+ assert(sizeof(struct FipEntry) == 40);
+
+ toc_buf = malloc(0x4000);
+ if (toc_buf == NULL) {
+ perror("malloc");
+ return 1;
+ }
+
+ ptoc = (struct FipHeader *)toc_buf;
+ toc_pos = ftell(fout);
+ fread(toc_buf, 1, 0x4000, fin);
+ n = 0;
+ while (ptoc->entries[n].size != 0) {
+ n++;
+ }
+ fwrite(toc_buf, 1, 0x4000, fout);
+
+ buf = malloc(0x10000);
+ if (buf == NULL) {
+ perror("malloc");
+ return 1;
+ }
+
+ for (i = 0; i < n; i++) {
+ struct AmlogicHeader fip_hdr = {
+ .sig = AMLOGIC_SIGNATURE,
+ .size = 64,
+ .header_size = sizeof(struct AmlogicHeader),
+ .header_version = 1,
+ .digest_size = SHA256_DIGEST_LENGTH,
+ };
+ SHA256_CTX sha256_ctx;
+ uint8_t sha256_digest[SHA256_DIGEST_LENGTH];
+ size_t len;
+ long pos;
+ long remaining;
+ int padlen;
+
+ pos = ftell(fout);
+
+ printf("FIP TOC entry offset_address: %" PRIx64 "\n", ptoc->entries[i].offset_address);
+ printf("FIP TOC entry size: %" PRIx64 "\n", ptoc->entries[i].size);
+
+ fseek(fin, toc_pos + ptoc->entries[i].offset_address, SEEK_SET);
+ printf("Input at %lx\n", ftell(fin));
+
+ len = ptoc->entries[i].size & (16 - 1);
+ padlen = (len != 0) ? (16 - len) : 0;
+
+ memset(buf, 0, 0x10000);
+ fip_hdr.size += fip_hdr.digest_size + ptoc->entries[i].size + padlen;
+#ifdef COMPARE_MODE
+ fip_hdr.id = 0x4ee06c7b;
+#else
+#ifdef REPRODUCIBLE_OUTPUT
+ fip_hdr.id = 0x42424200 + i;
+#else
+#error Non-reproducible FIP image IDs not implemented.
+#endif
+#endif
+ fip_hdr.digest_offset = fip_hdr.header_size;
+ fip_hdr.data_offset = fip_hdr.digest_offset + fip_hdr.digest_size;
+ fip_hdr.padding_offset = fip_hdr.data_offset;
+ fip_hdr._offset2 = fip_hdr.size - 0x60;
+ fip_hdr.payload_size = fip_hdr.size - 0x60;
+ fip_hdr.payload_offset = fip_hdr.header_size + SHA256_DIGEST_LENGTH;
+ memcpy(buf, &fip_hdr, sizeof(fip_hdr));
+
+ fwrite(buf, 1, fip_hdr.header_size + fip_hdr.digest_size, fout);
+
+ SHA256_Init(&sha256_ctx);
+ SHA256_Update(&sha256_ctx, buf, fip_hdr.header_size);
+ SHA256_Update(&sha256_ctx, buf + fip_hdr.data_offset, 0);
+ remaining = ptoc->entries[i].size;
+ len = fread(buf, 1, fip_hdr.header_size + fip_hdr.digest_size, fin);
+ if (strncmp(buf + 16, "@AML", 4) == 0) {
+ fprintf(stderr, "@AML discovered in input FIP section %i!\n", i);
+ return 1;
+ }
+ SHA256_Update(&sha256_ctx, buf, len);
+ remaining -= len;
+ while (remaining > 0) {
+ len = fread(buf, 1, MIN(remaining, 0x4000), fin);
+ remaining -= len;
+ memset(buf + len, 0, len & 0xf);
+ SHA256_Update(&sha256_ctx, buf, ROUND_UP(len, 16));
+ fwrite(buf, 1, ROUND_UP(len, 16), fout);
+ }
+ SHA256_Final(sha256_digest, &sha256_ctx);
+ fseek(fout, pos + fip_hdr.digest_offset, SEEK_SET);
+ fwrite(sha256_digest, 1, sizeof(sha256_digest), fout);
+ fseek(fout, 0, SEEK_END);
+
+ fseek(fin, toc_pos + ptoc->entries[i].offset_address, SEEK_SET);
+ len = fread(buf, 1, fip_hdr.header_size + fip_hdr.digest_size, fin);
+ fwrite(buf, 1, len, fout);
+
+ ptoc->entries[i].size += fip_hdr.header_size + fip_hdr.digest_size + padlen;
+ printf("FIP TOC entry size: %" PRIx64 "\n", ptoc->entries[i].size);
+ len = ptoc->entries[i].size & (0x4000 - 1);
+ if (len != 0) {
+ len = 0x4000 - len;
+ memset(buf, 0, len);
+ fwrite(buf, 1, len, fout);
+ }
+ }
+ free(buf);
+ fseek(fout, toc_pos, SEEK_SET);
+ fwrite(toc_buf, 1, 0x4000, fout);
+ fseek(fout, 0, SEEK_END);
+ free(toc_buf);
+ return 0;
+}
+
+static int boot_sig(const char *input, const char *output)
+{
+ FILE *fin, *fout;
+ uint8_t random[16];
+ char *src_buf, *buf;
+ struct AmlogicHeader hdr = {
+ .sig = AMLOGIC_SIGNATURE,
+ .size = 64,
+ .header_size = 64,
+ .header_version = 1,
+ .encrypted = 0,
+ .digest_offset = 64,
+ .digest_size = 512,
+ };
+ SHA256_CTX sha256_ctx;
+ uint8_t sha256_digest[SHA256_DIGEST_LENGTH];
+#ifndef COMPARE_MODE
+ int i;
+#endif
+
+ assert(sizeof(struct AmlogicHeader) == 64);
+
+ src_buf = malloc(0xb000);
+ if (src_buf == NULL)
+ return 1;
+
+ fin = fopen(input, "rb");
+ if (fin == NULL) {
+ perror(input);
+ return 1;
+ }
+
+ fout = fopen(output, "wb");
+ if (fout == NULL) {
+ perror(output);
+ return 1;
+ }
+
+#ifdef COMPARE_MODE
+ memcpy(random, (uint8_t[]){ 0xde, 0x49, 0x4c, 0x47, 0xe1, 0xd4, 0x86, 0xca, 0xb7, 0x4f, 0x10, 0xa4, 0x29, 0x3f, 0x28, 0x00 }, 16);
+#else
+ for (i = 0; i < 16; i++)
+#ifdef REPRODUCIBLE_OUTPUT
+ random[i] = 0x42;
+#else
+ random[i] = rand();
+#endif
+#endif
+
+ (void)fwrite(random, 1, 16, fout);
+
+ (void)fread(src_buf, 1, 0xb000, fin);
+
+ if (strncmp(src_buf + 16, "@AML", 4) == 0) {
+ fprintf(stderr, "@AML discovered in input!\n");
+ return 1;
+ }
+
+ fseek(fin, 0xc000, SEEK_SET);
+
+ hdr.size += hdr.digest_size;
+ hdr.size += 0xdb0;
+ hdr.size += 0xb000;
+ hdr.digest_offset = hdr.header_size;
+ hdr.data_offset = hdr.header_size + SHA256_DIGEST_LENGTH;
+ hdr.padding_offset = hdr.digest_offset + 512;
+ hdr.padding_size = 3504;
+ hdr._offset2 = hdr.size - hdr.data_offset;
+ hdr.payload_offset = hdr.padding_offset + hdr.padding_size;
+ hdr.payload_size = 0xb000;
+
+ buf = malloc(hdr.size);
+ if (buf == NULL) {
+ perror("malloc");
+ return 1;
+ }
+
+ memset(buf, 0, hdr.size);
+ memcpy(buf, &hdr, sizeof(struct AmlogicHeader));
+ memcpy(buf + hdr.padding_offset + hdr.padding_size, src_buf, 0xb000);
+
+ SHA256_Init(&sha256_ctx);
+ SHA256_Update(&sha256_ctx, buf, hdr.header_size);
+ SHA256_Update(&sha256_ctx, buf + hdr.data_offset, hdr._offset2);
+ memset(sha256_digest, 0, sizeof(sha256_digest));
+ SHA256_Final(sha256_digest, &sha256_ctx);
+ memcpy(buf + hdr.digest_offset, sha256_digest, sizeof(sha256_digest));
+
+ fwrite(buf, 1, hdr.size, fout);
+
+ if (do_fip(fout, fin) != 0)
+ return 1;
+
+ fclose(fout);
+ fclose(fin);
+
+ free(src_buf);
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ if (argc < 3) {
+ fprintf(stderr, "Usage: %s input output\n", argv[0]);
+ return 1;
+ }
+
+ return boot_sig(argv[1], argv[2]);
+}
diff --git a/board/hardkernel/odroid-c2/meson-tools/amlinfo.c b/board/hardkernel/odroid-c2/meson-tools/amlinfo.c
new file mode 100644
index 0000000000..06330c01d3
--- /dev/null
+++ b/board/hardkernel/odroid-c2/meson-tools/amlinfo.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2017 Andreas Färber
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "meson.h"
+
+static void print_aml_header(const struct AmlogicHeader *hdr)
+{
+ printf("Size: 0x%" PRIx32 "\n", hdr->size);
+ printf("Header size: 0x%" PRIx16 "\n", hdr->header_size);
+ printf("Header version: %" PRIu16 "\n", hdr->header_version);
+ printf("ID: 0x%" PRIx32 "\n", hdr->id);
+ printf("Encrypted? %" PRIu32 "\n", hdr->encrypted);
+ printf("Digest @ 0x%" PRIx32 ", len %" PRIu32 "\n", hdr->digest_offset, hdr->digest_size);
+ printf("Data @ 0x%" PRIx32 ", len %" PRIu32 "\n", hdr->data_offset, hdr->data_size);
+ printf("Padding @ 0x%" PRIx32 ", len %" PRIu32 "\n", hdr->padding_offset, hdr->padding_size);
+ printf("_offset2: 0x%" PRIx32 "\n", hdr->_offset2);
+ printf("pad2: 0x%" PRIx32 "\n", hdr->pad2);
+ printf("Payload @ 0x%" PRIx32 ", len %" PRIu32 "\n", hdr->payload_offset, hdr->payload_size);
+ printf("unknown: 0x%" PRIx32 "\n", hdr->unknown);
+ printf("\n");
+}
+
+static int info(char *filename)
+{
+ uint8_t buf[16 + 64];
+ struct AmlogicHeader *hdr;
+ FILE *f;
+ long pos;
+ int len;
+
+ f = fopen(filename, "rb");
+ if (f == NULL)
+ return 1;
+
+ pos = 0;
+ do {
+ len = fread(buf, 1, 16 + 64, f);
+ if (len >= 4 && strncmp((const char*)buf, AMLOGIC_SIGNATURE, 4) == 0) {
+ hdr = (struct AmlogicHeader *)buf;
+ pos += 0;
+ } else if (len >= 16 + 4 && strncmp((const char*)buf + 16, AMLOGIC_SIGNATURE, 4) == 0) {
+ hdr = (struct AmlogicHeader *)(buf + 16);
+ pos += 16;
+ } else if (len >= 4 && ((struct FipHeader *)buf)->name == FIP_SIGNATURE) {
+ struct FipHeader *fip_hdr;
+ long toc_pos = pos;
+ int i = 0;
+
+ fip_hdr = malloc(sizeof(struct FipHeader) + sizeof(struct FipEntry));
+ if (fip_hdr == NULL)
+ return 1;
+ fseek(f, toc_pos, SEEK_SET);
+ len = fread(fip_hdr, 1, sizeof(struct FipHeader) + sizeof(struct FipEntry), f);
+ printf("FIP header @ 0x%" PRIx64 " (flags 0x%" PRIx64 ")\n", pos, fip_hdr->flags);
+ printf("\n");
+ while (fip_hdr->entries[0].size > 0) {
+ printf("FIP TOC entry %u (flags 0x%" PRIx64 ")\n", i, fip_hdr->entries[0].flags);
+ fseek(f, toc_pos + fip_hdr->entries[0].offset_address, SEEK_SET);
+ len = fread(buf, 1, 64, f);
+ if (len >= 4 && strncmp((const char*)buf, AMLOGIC_SIGNATURE, 4) == 0) {
+ printf("@AML header @ 0x%" PRIx64 "\n", toc_pos + fip_hdr->entries[0].offset_address);
+ print_aml_header((struct AmlogicHeader *)buf);
+ } else {
+ fprintf(stderr, "Unexpected FIP TOC entry contents\n");
+ }
+
+ i++;
+ fseek(f, toc_pos + sizeof(struct FipHeader) + i * sizeof(struct FipEntry), SEEK_SET);
+ fread((void*)fip_hdr + sizeof(struct FipHeader), 1, sizeof(struct FipEntry), f);
+ }
+ free(fip_hdr);
+ break;
+ } else {
+ fclose(f);
+ return 1;
+ }
+
+ printf("@AML header @ 0x%" PRIx64 "\n", pos);
+ print_aml_header(hdr);
+
+ fseek(f, pos + hdr->size, SEEK_SET);
+ } while ((pos = ftell(f)) > 0);
+
+ fclose(f);
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s filename\n", argv[0]);
+ return 1;
+ }
+ return info(argv[1]);
+}
diff --git a/board/hardkernel/odroid-c2/meson-tools/fip.h b/board/hardkernel/odroid-c2/meson-tools/fip.h
new file mode 100644
index 0000000000..319a86ff8b
--- /dev/null
+++ b/board/hardkernel/odroid-c2/meson-tools/fip.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017 Andreas Färber
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR MIT
+ */
+
+#ifndef MESON_FIP_H
+#define MESON_FIP_H
+
+#include <stdint.h>
+
+#define FIP_SIGNATURE 0xaa640001
+
+struct __attribute((__packed__)) FipEntry {
+ uint64_t uuid[2];
+ uint64_t offset_address;
+ uint64_t size;
+ uint64_t flags;
+};
+
+struct __attribute((__packed__)) FipHeader {
+ uint32_t name;
+ uint32_t serial_number;
+ uint64_t flags;
+ struct FipEntry entries[0];
+};
+
+#endif
diff --git a/board/hardkernel/odroid-c2/meson-tools/meson.h b/board/hardkernel/odroid-c2/meson-tools/meson.h
new file mode 100644
index 0000000000..1fd1cb369e
--- /dev/null
+++ b/board/hardkernel/odroid-c2/meson-tools/meson.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2017 Andreas Färber
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef MESON_COMMON_H
+#define MESON_COMMON_H
+
+#include "fip.h"
+#include "aml.h"
+
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef ROUND_UP
+#define ROUND_UP(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
+#endif
+
+#endif
diff --git a/board/hardkernel/odroid-c2/meson-tools/unamlbootsig.c b/board/hardkernel/odroid-c2/meson-tools/unamlbootsig.c
new file mode 100644
index 0000000000..523fc6f268
--- /dev/null
+++ b/board/hardkernel/odroid-c2/meson-tools/unamlbootsig.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2017 Andreas Färber
+ *
+ * SPLX-License-Identifier: GPL-2.0+
+ */
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "meson.h"
+
+static int extract(const char *input, const char *output)
+{
+ uint8_t buf[16 + sizeof(struct AmlogicHeader)];
+ struct AmlogicHeader *hdr;
+ FILE *fin, *fout;
+ long pos;
+ int len;
+
+ fin = fopen(input, "rb");
+ if (fin == NULL)
+ return 1;
+
+ fout = fopen(output, "wb");
+ if (fout == NULL)
+ return 1;
+
+ pos = 0;
+ do {
+ len = fread(buf, 1, 16 + sizeof(struct AmlogicHeader), fin);
+ if (len >= 4 && strncmp((const char*)buf, AMLOGIC_SIGNATURE, 4) == 0) {
+ hdr = (struct AmlogicHeader *)buf;
+ } else if (len >= 16 + 4 && strncmp((const char*)buf + 16, AMLOGIC_SIGNATURE, 4) == 0) {
+ hdr = (struct AmlogicHeader *)(buf + 16);
+ pos += 16;
+ } else if (len >= 4 && ((struct FipHeader *)buf)->name == FIP_SIGNATURE) {
+ struct FipHeader *fip_hdr;
+ uint8_t *src_buf;
+ long toc_pos = pos;
+ int i, n;
+
+ fip_hdr = malloc(sizeof(struct FipHeader) + sizeof(struct FipEntry));
+ if (fip_hdr == NULL)
+ return 1;
+ fseek(fin, toc_pos, SEEK_SET);
+ len = fread(fip_hdr, 1, sizeof(struct FipHeader) + sizeof(struct FipEntry), fin);
+ printf("FIP header @ 0x%" PRIx64 " (flags 0x%" PRIx64 ")\n", pos, fip_hdr->flags);
+ fwrite(fip_hdr, 1, sizeof(struct FipHeader), fout);
+ n = 0;
+ while (fip_hdr->entries[0].size > 0) {
+ n++;
+ fread((void*)fip_hdr + sizeof(struct FipHeader), 1, sizeof(struct FipEntry), fin);
+ }
+ fip_hdr = realloc(fip_hdr, sizeof(struct FipHeader) + (n + 1) * sizeof(struct FipEntry));
+ if (fip_hdr == NULL)
+ return 1;
+
+ fseek(fin, toc_pos + sizeof(struct FipHeader), SEEK_SET);
+ fread((void*)fip_hdr + sizeof(struct FipHeader), 1, (n + 1) * sizeof(struct FipEntry), fin);
+ fwrite((void *)fip_hdr + sizeof(struct FipHeader), 1, (n + 1) * sizeof(struct FipEntry), fout);
+ src_buf = malloc(0x4000);
+ if (src_buf == NULL)
+ return 1;
+
+ for (i = 0; i < n; i++) {
+ printf("FIP TOC entry %u (flags 0x%" PRIx64 ")\n", i, fip_hdr->entries[i].flags);
+
+ fseek(fin, toc_pos + fip_hdr->entries[i].offset_address, SEEK_SET);
+ len = fread(buf, 1, sizeof(struct AmlogicHeader), fin);
+ if (len >= 4 && strncmp((const char*)buf, AMLOGIC_SIGNATURE, 4) == 0) {
+ long remaining;
+
+ printf("@AML header @ 0x%" PRIx64 "\n", toc_pos + fip_hdr->entries[i].offset_address);
+ hdr = (struct AmlogicHeader *)buf;
+ fip_hdr->entries[i].size -= hdr->header_size + hdr->digest_size;
+ pos = ftell(fout);
+ pos = ROUND_UP(pos, 0x4000);
+ fseek(fout, pos, SEEK_SET);
+ fseek(fin, toc_pos + fip_hdr->entries[i].offset_address + fip_hdr->entries[i].size, SEEK_SET);
+ len = fread(src_buf, 1, hdr->header_size + hdr->digest_size, fin);
+ fwrite(src_buf, 1, len, fout);
+
+ fseek(fin, toc_pos + fip_hdr->entries[i].offset_address + hdr->header_size + hdr->digest_size, SEEK_SET);
+ remaining = fip_hdr->entries[i].size - hdr->header_size - hdr->digest_size;
+ while (remaining > 0) {
+ len = fread(src_buf, 1, MIN(remaining, 0x4000), fin);
+ remaining -= len;
+ fwrite(src_buf, 1, len, fout);
+ }
+ } else {
+ fprintf(stderr, "Unexpected FIP TOC entry contents\n");
+ }
+ }
+ fseek(fout, 0xc000, SEEK_SET);
+ fwrite(fip_hdr, 1, sizeof(struct FipHeader) + (n + 1) * sizeof(struct FipEntry), fout);
+ fseek(fout, 0, SEEK_END);
+ pos = ftell(fout);
+ pos = ROUND_UP(pos, 0x4000);
+ fseek(fout, pos - 1, SEEK_SET);
+ buf[0] = 0;
+ fwrite(buf, 1, 1, fout);
+ free(fip_hdr);
+ break;
+ } else {
+ fclose(fout);
+ fclose(fin);
+ return 1;
+ }
+
+ printf("@AML header @ 0x%" PRIx64 "\n", pos);
+
+ fseek(fin, pos + hdr->payload_offset, SEEK_SET);
+ uint8_t *src_buf = malloc(hdr->payload_size);
+ if (src_buf == NULL) {
+ fclose(fout);
+ fclose(fin);
+ return 1;
+ }
+ len = fread(src_buf, 1, hdr->payload_size, fin);
+ fwrite(src_buf, 1, len, fout);
+ free(src_buf);
+
+ fseek(fin, pos + hdr->size, SEEK_SET);
+ fseek(fout, 0xc000, SEEK_SET);
+ } while ((pos = ftell(fin)) > 0);
+
+ fclose(fout);
+ fclose(fin);
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ if (argc < 3) {
+ fprintf(stderr, "Usage: %s input output\n", argv[0]);
+ return 1;
+ }
+ return extract(argv[1], argv[2]);
+}
diff --git a/board/hardkernel/odroid-c2/sd_fusing.sh b/board/hardkernel/odroid-c2/sd_fusing.sh
new file mode 100755
index 0000000000..c5a517ca75
--- /dev/null
+++ b/board/hardkernel/odroid-c2/sd_fusing.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# Copyright (C) 2015 Hardkernel Co,. Ltd
+# Dongjin Kim <tobetter@gmail.com>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+BL1=bl1.bin.hardkernel
+UBOOT=u-boot.bin
+
+if [ -z $1 ]; then
+ echo "Usage ./sd_fusing.sh <SD card reader's device>"
+ exit 1
+fi
+
+if [ ! -f $BL1 ]; then
+ echo "error: $BL1 does not exist"
+ exit 1
+fi
+
+if [ ! -f $UBOOT ]; then
+ echo "error: $UBOOT does not exist"
+ exit 1
+fi
+
+sudo dd if=$BL1 of=$1 conv=fsync,notrunc bs=1 count=442
+sudo dd if=$BL1 of=$1 conv=fsync,notrunc bs=512 skip=1 seek=1
+sudo dd if=$UBOOT of=$1 conv=fsync,notrunc bs=512 seek=97
+
+sync
+
+sudo eject $1
+echo Finished.