[PATCH 2/3] scripts: arch: imx: Add QSPI boot support to IMX build image script

Joacim Zetterling joacim.zetterling at westermo.com
Tue Mar 8 08:08:00 PST 2022


This functionality extend the IMX image build script with a support
for generating QSPI boot images.

A QSPI boot image need device configuration parameters located at
an offset of 0x400 in the IVT section. The configuration parameters
are stored in a 512 byte bin file which will be included in the
final boot image. The boot image parameters comes from the board
flash header imxcfg file.

The QSPI configuration parameters are described in the reference
manual for the specific target.

Signed-off-by: Joacim Zetterling <joacim.zetterling at westermo.com>
---
 arch/arm/mach-imx/include/mach/imx-header.h |  2 +
 scripts/imx/imx-image.c                     | 25 ++++++++
 scripts/imx/imx.c                           | 67 ++++++++++++++++++++-
 3 files changed, 93 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-imx/include/mach/imx-header.h b/arch/arm/mach-imx/include/mach/imx-header.h
index 8e968e6efba3..a58deb8d864e 100644
--- a/arch/arm/mach-imx/include/mach/imx-header.h
+++ b/arch/arm/mach-imx/include/mach/imx-header.h
@@ -118,6 +118,8 @@ struct config_data {
 	char *signed_hdmi_firmware_file;
 	int encrypt_image;
 	size_t dek_size;
+	uint32_t bb_cfg_ofs;
+	char *bb_cfg_file;
 };
 
 #define MAX_RECORDS_DCD_V2 1024
diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c
index 439912a805dc..b8ae63ad9400 100644
--- a/scripts/imx/imx-image.c
+++ b/scripts/imx/imx-image.c
@@ -951,6 +951,31 @@ int main(int argc, char *argv[])
 			exit(1);
 		}
 
+		/*
+		* The boot ROM expects a 512-byte configuration parameters area for
+		* some devices (like the FlexSPI NOR flash) to be present an defined
+		* offset in the image ivt section (0x400 for the FlexSPI NOR).
+		*/
+		if (data.bb_cfg_file) {
+			size_t bb_cfg_file_size = 512;
+			char *bb_cfg;
+
+			bb_cfg = calloc(512, sizeof(char));
+			if (!bb_cfg)
+				exit(1);
+
+			bb_cfg = read_file(data.bb_cfg_file, &bb_cfg_file_size);
+
+			if (lseek(outfd, data.bb_cfg_ofs, SEEK_SET) < 0) {
+				perror("lseek");
+				exit(1);
+			}
+
+			xwrite(outfd, bb_cfg, bb_cfg_file_size);
+
+			free(bb_cfg);
+		}
+
 		if (lseek(outfd, data.header_gap, SEEK_SET) < 0) {
 			perror("lseek");
 			exit(1);
diff --git a/scripts/imx/imx.c b/scripts/imx/imx.c
index 87560ad27de1..a242e6d76a47 100644
--- a/scripts/imx/imx.c
+++ b/scripts/imx/imx.c
@@ -215,6 +215,16 @@ static int do_dcdofs_error(struct config_data *data, int argc, char *argv[])
 	return -EINVAL;
 }
 
+static int do_header_gap(struct config_data *data, int argc, char *argv[])
+{
+	if (argc < 2)
+		return -EINVAL;
+
+	data->header_gap = strtoul(argv[1], NULL, 0);
+
+	return 0;
+}
+
 struct soc_type {
 	char *name;
 	int header_version;
@@ -223,6 +233,7 @@ struct soc_type {
 	uint32_t first_opcode;
 };
 
+#define SZ_4K	(4 * 1024)
 #define SZ_32K	(32 * 1024)
 
 static struct soc_type socs[] = {
@@ -580,7 +591,6 @@ do_signed_hdmi_firmware(struct config_data *data, int argc, char *argv[])
 	const char *file;
 	int len;
 
-
 	if (argc != 2) {
 		fprintf(stderr, "usage: signed_hdmi_firmware <file>\n");
 		return -EINVAL;
@@ -609,6 +619,52 @@ do_signed_hdmi_firmware(struct config_data *data, int argc, char *argv[])
 	return 0;
 }
 
+static int do_bb_cfg_ofs(struct config_data *data, int argc, char *argv[])
+{
+	if (argc < 2)
+		return -EINVAL;
+
+	data->bb_cfg_ofs = strtoul(argv[1], NULL, 0);
+
+	return 0;
+}
+
+static int do_bb_cfg_file(struct config_data *data, int argc, char *argv[])
+{
+	const char *file;
+	int len;
+
+	if (argc != 2) {
+		fprintf(stderr, "usage: bb_cfg_file <file>\n");
+		return -EINVAL;
+	}
+
+	if ((data->cpu_type != IMX_CPU_IMX8MM) && 
+		(data->cpu_type != IMX_CPU_IMX8MN) && 
+		(data->cpu_type != IMX_CPU_IMX8MP) &&
+		(data->cpu_type != IMX_CPU_IMX8MQ)) {
+		fprintf(stderr,
+			"Warning: The configuration param command is "
+			"only supported i.MX8 SoCs\n");
+		return 0;
+	}
+
+	file = argv[1];
+
+	if (*file == '"')
+		file++;
+
+	data->bb_cfg_file = strdup(file);
+	if (!data->bb_cfg_file)
+		return -ENOMEM;
+
+	len = strlen(data->bb_cfg_file);
+	if (data->bb_cfg_file[len - 1] == '"')
+		data->bb_cfg_file[len - 1] = 0;
+
+	return 0;
+}
+
 struct command cmds[] = {
 	{
 		.name = "wm",
@@ -634,6 +690,9 @@ struct command cmds[] = {
 	}, {
 		.name = "dcdofs",
 		.parse = do_dcdofs_error,
+	}, {
+		.name = "header_gap",
+		.parse = do_header_gap,
 	}, {
 		.name = "soc",
 		.parse = do_soc,
@@ -667,6 +726,12 @@ struct command cmds[] = {
 	}, {
 		.name = "signed_hdmi_firmware",
 		.parse = do_signed_hdmi_firmware,
+	}, {
+		.name = "bb_cfg_ofs",
+		.parse = do_bb_cfg_ofs,
+	}, {
+		.name = "bb_cfg_file",
+		.parse = do_bb_cfg_file,
 	},
 };
 
-- 
2.25.1




More information about the barebox mailing list