[Sound-open-firmware] [PATCH] rimage: add support for automatic MEU signing

Liam Girdwood liam.r.girdwood at linux.intel.com
Mon Jun 4 13:03:42 CEST 2018


From: Tomasz Lauda <tomasz.lauda at linux.intel.com>

This patch allows rimage to sign FW binaries using MEU tool.
Paths to MEU and private key have to be provided during config step.

Signed-off-by: Tomasz Lauda <tomasz.lauda at linux.intel.com>
---
 .gitignore                  |   1 +
 configure.ac                |  31 ++++++-
 m4/ax_compare_version.m4    | 178 ++++++++++++++++++++++++++++++++++++
 rimage/manifest.c           | 172 ++++++++++++++++++++++++++--------
 rimage/plat_auth.c          |   7 +-
 rimage/plat_auth.h          |   3 +-
 rimage/rimage.c             |  10 +-
 rimage/rimage.h             |   3 +-
 src/arch/xtensa/Makefile.am |  12 ++-
 9 files changed, 368 insertions(+), 49 deletions(-)
 create mode 100644 m4/ax_compare_version.m4

diff --git a/.gitignore b/.gitignore
index c03c83e..8558441 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,7 @@
 .build
 *.dis
 *.lst
+*.log
 .*
 
 Makefile
diff --git a/configure.ac b/configure.ac
index 0d810b3..3420530 100644
--- a/configure.ac
+++ b/configure.ac
@@ -27,8 +27,35 @@ AC_SUBST(ASFLAGS)
 
 # Cross compiler tool libgcc and headers
 AC_ARG_WITH([root-dir],
-        AS_HELP_STRING([--with-root-dir], [Specify location of cross gcc libraries and headers]),
-        [], [with_root_dir=no])
+		AS_HELP_STRING([--with-root-dir], [Specify location of cross gcc libraries and headers]),
+		[], [with_root_dir=no])
+
+# MEU location
+AC_ARG_WITH([meu],
+		AS_HELP_STRING([--with-meu], [Specify location of MEU tool]),
+		[], [with_meu=no])
+if test "x$with_meu" != "xno"; then
+	MEU_PATH="$with_meu"
+	AC_SUBST(MEU_PATH)
+
+	MEU_VERSION=$($with_meu/meu -ver | grep "Version:" | cut -d" " -f6)
+	AX_COMPARE_VERSION([$MEU_VERSION], [ge], [12.0.0.1035], [MEU_OFFSET=1088], [MEU_OFFSET=1152])
+	AC_SUBST(MEU_OFFSET)
+fi
+AM_CONDITIONAL(USE_MEU, test "x$with_meu" != "xno")
+
+# Private key location
+AC_ARG_WITH([key],
+		AS_HELP_STRING([--with-key], [Specify location of private key]),
+		[], [with_key=no])
+if test "x$with_meu" != "xno"; then
+	if test "x$with_key" != "xno"; then
+		PRIVATE_KEY="$with_key"
+		AC_SUBST(PRIVATE_KEY)
+	else
+		AC_MSG_ERROR([Private key location not specified])
+	fi
+fi
 
 # check if we are building FW image or library
 AC_ARG_ENABLE(library, [AS_HELP_STRING([--enable-library],[build library])], have_library=$enableval, have_library=no)
diff --git a/m4/ax_compare_version.m4 b/m4/ax_compare_version.m4
new file mode 100644
index 0000000..6df1c53
--- /dev/null
+++ b/m4/ax_compare_version.m4
@@ -0,0 +1,178 @@
+# ===========================================================================
+#    https://www.gnu.org/software/autoconf-archive/ax_compare_version.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
+#
+# DESCRIPTION
+#
+#   This macro compares two version strings. Due to the various number of
+#   minor-version numbers that can exist, and the fact that string
+#   comparisons are not compatible with numeric comparisons, this is not
+#   necessarily trivial to do in a autoconf script. This macro makes doing
+#   these comparisons easy.
+#
+#   The six basic comparisons are available, as well as checking equality
+#   limited to a certain number of minor-version levels.
+#
+#   The operator OP determines what type of comparison to do, and can be one
+#   of:
+#
+#    eq  - equal (test A == B)
+#    ne  - not equal (test A != B)
+#    le  - less than or equal (test A <= B)
+#    ge  - greater than or equal (test A >= B)
+#    lt  - less than (test A < B)
+#    gt  - greater than (test A > B)
+#
+#   Additionally, the eq and ne operator can have a number after it to limit
+#   the test to that number of minor versions.
+#
+#    eq0 - equal up to the length of the shorter version
+#    ne0 - not equal up to the length of the shorter version
+#    eqN - equal up to N sub-version levels
+#    neN - not equal up to N sub-version levels
+#
+#   When the condition is true, shell commands ACTION-IF-TRUE are run,
+#   otherwise shell commands ACTION-IF-FALSE are run. The environment
+#   variable 'ax_compare_version' is always set to either 'true' or 'false'
+#   as well.
+#
+#   Examples:
+#
+#     AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8])
+#     AX_COMPARE_VERSION([3.15],[lt],[3.15.8])
+#
+#   would both be true.
+#
+#     AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8])
+#     AX_COMPARE_VERSION([3.15],[gt],[3.15.8])
+#
+#   would both be false.
+#
+#     AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8])
+#
+#   would be true because it is only comparing two minor versions.
+#
+#     AX_COMPARE_VERSION([3.15.7],[eq0],[3.15])
+#
+#   would be true because it is only comparing the lesser number of minor
+#   versions of the two values.
+#
+#   Note: The characters that separate the version numbers do not matter. An
+#   empty string is the same as version 0. OP is evaluated by autoconf, not
+#   configure, so must be a string, not a variable.
+#
+#   The author would like to acknowledge Guido Draheim whose advice about
+#   the m4_case and m4_ifvaln functions make this macro only include the
+#   portions necessary to perform the specific comparison specified by the
+#   OP argument in the final configure script.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Tim Toolan <toolan at ele.uri.edu>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 13
+
+dnl #########################################################################
+AC_DEFUN([AX_COMPARE_VERSION], [
+  AC_REQUIRE([AC_PROG_AWK])
+
+  # Used to indicate true or false condition
+  ax_compare_version=false
+
+  # Convert the two version strings to be compared into a format that
+  # allows a simple string comparison.  The end result is that a version
+  # string of the form 1.12.5-r617 will be converted to the form
+  # 0001001200050617.  In other words, each number is zero padded to four
+  # digits, and non digits are removed.
+  AS_VAR_PUSHDEF([A],[ax_compare_version_A])
+  A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
+                     -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
+                     -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+                     -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+                     -e 's/[[^0-9]]//g'`
+
+  AS_VAR_PUSHDEF([B],[ax_compare_version_B])
+  B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
+                     -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
+                     -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+                     -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+                     -e 's/[[^0-9]]//g'`
+
+  dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary
+  dnl # then the first line is used to determine if the condition is true.
+  dnl # The sed right after the echo is to remove any indented white space.
+  m4_case(m4_tolower($2),
+  [lt],[
+    ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"`
+  ],
+  [gt],[
+    ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"`
+  ],
+  [le],[
+    ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"`
+  ],
+  [ge],[
+    ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"`
+  ],[
+    dnl Split the operator from the subversion count if present.
+    m4_bmatch(m4_substr($2,2),
+    [0],[
+      # A count of zero means use the length of the shorter version.
+      # Determine the number of characters in A and B.
+      ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'`
+      ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'`
+
+      # Set A to no more than B's length and B to no more than A's length.
+      A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"`
+      B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"`
+    ],
+    [[0-9]+],[
+      # A count greater than zero means use only that many subversions
+      A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
+      B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
+    ],
+    [.+],[
+      AC_WARNING(
+        [invalid OP numeric parameter: $2])
+    ],[])
+
+    # Pad zeros at end of numbers to make same length.
+    ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`"
+    B="$B`echo $A | sed 's/./0/g'`"
+    A="$ax_compare_version_tmp_A"
+
+    # Check for equality or inequality as necessary.
+    m4_case(m4_tolower(m4_substr($2,0,2)),
+    [eq],[
+      test "x$A" = "x$B" && ax_compare_version=true
+    ],
+    [ne],[
+      test "x$A" != "x$B" && ax_compare_version=true
+    ],[
+      AC_WARNING([invalid OP parameter: $2])
+    ])
+  ])
+
+  AS_VAR_POPDEF([A])dnl
+  AS_VAR_POPDEF([B])dnl
+
+  dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE.
+  if test "$ax_compare_version" = "true" ; then
+    m4_ifvaln([$4],[$4],[:])dnl
+    m4_ifvaln([$5],[else $5])dnl
+  fi
+]) dnl AX_COMPARE_VERSION
+
diff --git a/rimage/manifest.c b/rimage/manifest.c
index 257aa0d..b758717 100644
--- a/rimage/manifest.c
+++ b/rimage/manifest.c
@@ -539,12 +539,13 @@ static int man_module_create_reloc(struct image *image, struct module *module,
 	return 0;
 }
 
-static int man_write_unsigned_mod(struct image *image)
+static int man_write_unsigned_mod(struct image *image, int meta_start_offset,
+	int meta_end_offset)
 {
 	int count;
 
 	/* write metadata file for unsigned FW */
-	count = fwrite(image->fw_image + MAN_META_EXT_OFFSET,
+	count = fwrite(image->fw_image + meta_start_offset,
 			sizeof(struct sof_man_adsp_meta_file_ext), 1,
 			image->out_man_fd);
 
@@ -557,8 +558,8 @@ static int man_write_unsigned_mod(struct image *image)
 	fclose(image->out_man_fd);
 
 	/* now prepare the unsigned rimage */
-	count = fwrite(image->fw_image + MAN_FW_DESC_OFFSET,
-			image->image_end - MAN_FW_DESC_OFFSET,
+	count = fwrite(image->fw_image + meta_end_offset,
+			image->image_end - meta_end_offset,
 			1, image->out_unsigned_fd);
 
 	/* did the unsigned FW write succeed ? */
@@ -601,13 +602,59 @@ static int man_write_fw_mod(struct image *image)
 	return 0;
 }
 
+static int man_create_modules(struct image *image, struct sof_man_fw_desc *desc)
+{
+	struct module *module;
+	struct sof_man_module *man_module;
+	int err;
+	int i;
+
+	for (i = 0; i < image->num_modules; i++) {
+		man_module = sof_man_get_module(desc, i);
+		module = &image->module[i];
+
+		/* set module file offset */
+		if (i == 0)
+			module->foffset = FILE_TEXT_OFFSET;
+		else
+			module->foffset = image->image_end;
+
+		if (image->reloc)
+			err = man_module_create_reloc(image, module,
+						      man_module);
+		else
+			err = man_module_create(image, module, man_module);
+
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+static int man_hash_modules(struct image *image, struct sof_man_fw_desc *desc)
+{
+	struct sof_man_module *man_module;
+	int i;
+
+	for (i = 0; i < image->num_modules; i++) {
+		man_module = sof_man_get_module(desc, i);
+
+		ri_hash(image,
+			man_module->segment[SOF_MAN_SEGMENT_TEXT].file_offset,
+			(man_module->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length +
+			man_module->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length) *
+			MAN_PAGE_SIZE, man_module->hash);
+	}
+
+	return 0;
+}
+
 /* used by others */
 static int man_write_fw(struct image *image)
 {
 	struct sof_man_fw_desc *desc;
 	struct fw_image_manifest *m;
-	struct module *module;
-	struct sof_man_module *man_module;
 	uint8_t hash[SOF_MAN_MOD_SHA256_LEN];
 	int ret, i;
 
@@ -637,31 +684,13 @@ static int man_write_fw(struct image *image)
 
 	/* create each module */
 	m->desc.header.num_module_entries = image->num_modules;
-	for (i = 0; i < image->num_modules; i++) {
-
-		man_module = sof_man_get_module(desc, i);
-		module = &image->module[i];
-
-		/* set module file offset */
-		if (i == 0) {
-			module->foffset = FILE_TEXT_OFFSET;
-		} else {
-			module->foffset = image->image_end;
-		}
-
-		if (image->reloc)
-			ret = man_module_create_reloc(image, module,
-						      man_module);
-		else
-			ret = man_module_create(image, module, man_module);
-		if (ret < 0)
-			goto err;
-	}
+	man_create_modules(image, desc);
 
 	fprintf(stdout, "Firmware completing manifest\n");
 
 	/* create structures from end of file to start of file */
-	ri_adsp_meta_data_create(image);
+	ri_adsp_meta_data_create(image, MAN_META_EXT_OFFSET,
+				 MAN_FW_DESC_OFFSET);
 	ri_plat_ext_data_create(image);
 	ri_css_hdr_create(image);
 	ri_cse_create(image);
@@ -671,16 +700,7 @@ static int man_write_fw(struct image *image)
 		desc->header.preload_page_count);
 
 	/* calculate hash for each module */
-	for (i = 0; i < image->num_modules; i++) {
-
-		module = &image->module[i];
-		man_module = sof_man_get_module(desc, i);
-
-		ri_hash(image, man_module->segment[SOF_MAN_SEGMENT_TEXT].file_offset,
-			(man_module->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length +
-			man_module->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length) *
-			MAN_PAGE_SIZE, man_module->hash);
-	}
+	man_hash_modules(image, desc);
 
 	/* calculate hash for ADSP meta data extension - 0x480 to end */
 	ri_hash(image, MAN_FW_DESC_OFFSET, image->image_end
@@ -708,7 +728,8 @@ static int man_write_fw(struct image *image)
 		goto err;
 
 	/* write the unsigned files*/
-	ret = man_write_unsigned_mod(image);
+	ret = man_write_unsigned_mod(image, MAN_META_EXT_OFFSET,
+				     MAN_FW_DESC_OFFSET);
 	if (ret < 0)
 		goto err;
 
@@ -723,6 +744,79 @@ err:
 	return ret;
 }
 
+/* used to sign with MEU */
+static int man_write_fw_meu(struct image *image)
+{
+	const int meta_start_offset = image->meu_offset -
+		sizeof(struct sof_man_adsp_meta_file_ext) - MAN_EXT_PADDING;
+	struct sof_man_adsp_meta_file_ext *meta;
+	struct sof_man_fw_desc *desc;
+	uint32_t preload_size;
+	int ret;
+
+	/* allocate image */
+	image->fw_image = calloc(image->adsp->image_size, 1);
+	if (image->fw_image == NULL) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	/* open unsigned firmware */
+	ret = man_open_unsigned_file(image);
+	if (ret < 0)
+		goto err;
+
+	/* create the manifest */
+	ret = man_open_manifest_file(image);
+	if (ret < 0)
+		goto err;
+
+	/* create the module */
+	meta = image->fw_image + meta_start_offset;
+	desc = image->fw_image + MAN_DESC_OFFSET;
+
+	/* copy data */
+	memcpy(meta, &image->adsp->man->adsp_file_ext,
+	       sizeof(struct sof_man_adsp_meta_file_ext));
+	memcpy(desc, &image->adsp->man->desc,
+	       sizeof(struct sof_man_fw_desc));
+
+	/* create each module */
+	desc->header.num_module_entries = image->num_modules;
+	man_create_modules(image, desc);
+
+	fprintf(stdout, "Firmware completing manifest\n");
+
+	/* create structures from end of file to start of file */
+	ri_adsp_meta_data_create(image, meta_start_offset, image->meu_offset);
+
+	/* write preload page count */
+	preload_size = meta->comp_desc[0].limit_offset - MAN_DESC_OFFSET;
+	preload_size += MAN_PAGE_SIZE - (preload_size % MAN_PAGE_SIZE);
+	desc->header.preload_page_count = preload_size / MAN_PAGE_SIZE;
+
+	/* calculate hash for each module */
+	man_hash_modules(image, desc);
+
+	/* calculate hash for ADSP meta data extension */
+	ri_hash(image, image->meu_offset, image->image_end -
+		image->meu_offset, meta->comp_desc[0].hash);
+
+	/* write the unsigned files */
+	ret = man_write_unsigned_mod(image, meta_start_offset,
+				     image->meu_offset);
+	if (ret < 0)
+		goto err;
+
+	fprintf(stdout, "Firmware manifest completed!\n");
+	return 0;
+
+err:
+	free(image->fw_image);
+	unlink(image->out_file);
+	return ret;
+}
+
 #define ADSP_APL_DSP_ROM_BASE	0xBEFE0000
 #define ADSP_APL_DSP_ROM_SIZE	0x00002000
 #define APL_DSP_BASE_ENTRY	0xa000a000
@@ -743,6 +837,7 @@ const struct adsp machine_apl = {
 	.dram_offset = 0,
 	.machine_id = MACHINE_APOLLOLAKE,
 	.write_firmware = man_write_fw,
+	.write_firmware_meu = man_write_fw_meu,
 	.man = &apl_manifest,
 };
 
@@ -758,5 +853,6 @@ const struct adsp machine_cnl = {
 	.dram_offset = 0,
 	.machine_id = MACHINE_CANNONLAKE,
 	.write_firmware = man_write_fw,
+	.write_firmware_meu = man_write_fw_meu,
 	.man = &cnl_manifest,
 };
diff --git a/rimage/plat_auth.c b/rimage/plat_auth.c
index 21c7138..2fd62aa 100644
--- a/rimage/plat_auth.c
+++ b/rimage/plat_auth.c
@@ -18,15 +18,16 @@
 #include "manifest.h"
 #include "plat_auth.h"
 
-void ri_adsp_meta_data_create(struct image *image)
+void ri_adsp_meta_data_create(struct image *image, int meta_start_offset,
+	int meta_end_offset)
 {
 	struct sof_man_adsp_meta_file_ext *meta =
-		image->fw_image + MAN_META_EXT_OFFSET;
+		image->fw_image + meta_start_offset;
 
 	fprintf(stdout, " meta: completing ADSP manifest\n");
 
 	meta->comp_desc[0].limit_offset = MAN_DESC_OFFSET + image->image_end
-		- MAN_FW_DESC_OFFSET;
+		- meta_end_offset;
 
 	fprintf(stdout, " meta: limit is 0x%x\n",
 		meta->comp_desc[0].limit_offset);
diff --git a/rimage/plat_auth.h b/rimage/plat_auth.h
index 135f2d1..253a78b 100644
--- a/rimage/plat_auth.h
+++ b/rimage/plat_auth.h
@@ -86,7 +86,8 @@ struct partition_info_ext {
 	(sizeof(struct partition_info_ext) + \
 	sizeof(struct signed_pkg_info_ext))
 
-void ri_adsp_meta_data_create(struct image *image);
+void ri_adsp_meta_data_create(struct image *image, int meta_start_offset,
+	int meta_end_offset);
 void ri_plat_ext_data_create(struct image *image);
 
 #endif
diff --git a/rimage/rimage.c b/rimage/rimage.c
index cc0a610..e8b9dc8 100644
--- a/rimage/rimage.c
+++ b/rimage/rimage.c
@@ -39,6 +39,7 @@ static void usage(char *name)
 		name);
 	fprintf(stdout, "\t -v enable verbose output\n");
 	fprintf(stdout, "\t -r enable relocatable ELF files\n");
+	fprintf(stdout, "\t -s MEU signing offset\n");
 	exit(0);
 }
 
@@ -50,7 +51,7 @@ int main(int argc, char *argv[])
 
 	memset(&image, 0, sizeof(image));
 
-	while ((opt = getopt(argc, argv, "ho:m:vba:sk:l:r")) != -1) {
+	while ((opt = getopt(argc, argv, "ho:m:vba:s:k:l:r")) != -1) {
 		switch (opt) {
 		case 'o':
 			image.out_file = optarg;
@@ -62,7 +63,7 @@ int main(int argc, char *argv[])
 			image.verbose = 1;
 			break;
 		case 's':
-			image.dump_sections = 1;
+			image.meu_offset = atoi(optarg);
 			break;
 		case 'a':
 			image.abi = atoi(optarg);
@@ -130,7 +131,10 @@ found:
 	}
 
 	/* process and write output */
-	ret = image.adsp->write_firmware(&image);
+	if (image.meu_offset)
+		ret = image.adsp->write_firmware_meu(&image);
+	else
+		ret = image.adsp->write_firmware(&image);
 out:
 	/* close files */
 	if (image.out_fd)
diff --git a/rimage/rimage.h b/rimage/rimage.h
index 888e7e8..3398ece 100644
--- a/rimage/rimage.h
+++ b/rimage/rimage.h
@@ -99,7 +99,7 @@ struct image {
 	int num_modules;
 	struct module module[MAX_MODULES];
 	uint32_t image_end;/* module end, equal to output image size */
-	int dump_sections;
+	int meu_offset;
 
 	/* SHA 256 */
 	const char *key_name;
@@ -140,6 +140,7 @@ struct adsp {
 
 	enum machine_id machine_id;
 	int (*write_firmware)(struct image *image);
+	int (*write_firmware_meu)(struct image *image);
 	struct fw_image_manifest *man;
 };
 
diff --git a/src/arch/xtensa/Makefile.am b/src/arch/xtensa/Makefile.am
index 50d3ded..4ffe15f 100644
--- a/src/arch/xtensa/Makefile.am
+++ b/src/arch/xtensa/Makefile.am
@@ -151,13 +151,23 @@ MODULE_COPY=
 MODULE_INSERT=
 endif
 
+if USE_MEU
+RIMAGE=rimage -o sof-$(FW_NAME).ri -m $(FW_NAME) $(RIMAGE_BOOT_FLAGS) $(RIMAGE_FLAGS) -s $(MEU_OFFSET)
+MEU=$(MEU_PATH)/meu -w ./ -s sof-$(FW_NAME) -key $(PRIVATE_KEY) -stp /usr/bin/openssl -f $(MEU_PATH)/generic_meu_conf.xml \
+	-mnver 0.0.0.0 -o sof-$(FW_NAME).ri
+else
+RIMAGE=rimage -o sof-$(FW_NAME).ri -m $(FW_NAME) $(RIMAGE_BOOT_FLAGS) $(RIMAGE_FLAGS)
+MEU=
+endif
+
 bin-local: $(BIN_FLAGS)
 	cp sof sof-$(FW_NAME)
 	$(MODULE_COPY)
 	$(MODULE_INSERT)
 	$(OBJDUMP) -S sof-$(FW_NAME) > sof-$(FW_NAME).lst
 	$(OBJDUMP) -D sof-$(FW_NAME) > sof-$(FW_NAME).dis
-	rimage -o sof-$(FW_NAME).ri -m $(FW_NAME) $(RIMAGE_BOOT_FLAGS) $(RIMAGE_FLAGS)
+	$(RIMAGE)
+	$(MEU)
 
 vminstall-local:
 	scp -P 5555 sof-*.ri root at localhost:/lib/firmware/intel/
-- 
2.17.0



More information about the Sound-open-firmware mailing list