mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Jules Maselbas <jmaselbas@zdiv.net>
To: barebox@lists.infradead.org
Cc: Jules Maselbas <jmaselbas@zdiv.net>
Subject: [RFC PATCH 01/11] scripts: Add Allwinner eGON image support
Date: Thu, 11 May 2023 01:37:01 +0200	[thread overview]
Message-ID: <20230510233711.37345-2-jmaselbas@zdiv.net> (raw)
In-Reply-To: <20230510233711.37345-1-jmaselbas@zdiv.net>

On power-up Allwinner SoC starts in boot ROM, aka BROM, which will search
for an eGON image: first from the SD card, then from eMMC. If no image is
found then the BROM will enter into FEL mode that can be used for initial
programming and recovery of devices using USB.

The eGON header structure is adapted from u-boot: /include/sunxi_image.h,
the header structure is also documented on https://linux-sunxi.org/EGON

BROM will load, at most, the first 32KB of the image into SRAM, including
the header itself! The jump instruction in the header needs to be patched
accordingly with the image size.
---
 arch/arm/mach-sunxi/egon_header.c |  11 +++
 include/mach/sunxi/egon.h         |  63 ++++++++++++++++
 scripts/Kconfig                   |   7 ++
 scripts/Makefile                  |   1 +
 scripts/egon_mkimage.c            | 115 ++++++++++++++++++++++++++++++
 5 files changed, 197 insertions(+)
 create mode 100644 arch/arm/mach-sunxi/egon_header.c
 create mode 100644 include/mach/sunxi/egon.h
 create mode 100644 scripts/egon_mkimage.c

diff --git a/arch/arm/mach-sunxi/egon_header.c b/arch/arm/mach-sunxi/egon_header.c
new file mode 100644
index 0000000000..9a4822f71d
--- /dev/null
+++ b/arch/arm/mach-sunxi/egon_header.c
@@ -0,0 +1,11 @@
+#include <common.h>
+#include <mach/sunxi/egon.h>
+#if 0
+const struct egon_header sunxi_egon_header
+__attribute__((section(".text_egon_header"))) = {
+	 /* put a valid arm32 jump over the header, in order for images to
+	  * to work when not loaded by boot rom but by the FEL */
+	.branch = EGON_HDR_BRANCH,
+	.magic = "eGON",
+};
+#endif
diff --git a/include/mach/sunxi/egon.h b/include/mach/sunxi/egon.h
new file mode 100644
index 0000000000..f70730ee25
--- /dev/null
+++ b/include/mach/sunxi/egon.h
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef SUNIX_EGON
+#define SUNIX_EGON
+
+struct egon_header {
+	uint32_t branch; /* branch instruction to jump over the header */
+	uint8_t magic[8]; /* "eGON.BT0" or "eGON.BT1" */
+	uint32_t check_sum;
+	uint32_t length;
+	/*
+	 * We use a simplified header, only filling in what is needed
+	 * by the boot ROM. To be compatible with Allwinner tools we
+	 * would need to implement the proper fields here instead of
+	 * padding.
+	 *
+	 * Actually we want the ability to recognize our "sunxi" variant
+	 * of the SPL. To do so, let's place a special signature into the
+	 * "pub_head_size" field. We can reasonably expect Allwinner's
+	 * boot0 to always have the upper 16 bits of this set to 0 (after
+	 * all the value shouldn't be larger than the limit imposed by
+	 * SRAM size).
+	 * If the signature is present (at 0x14), then we know it's safe
+	 * to use the remaining 8 bytes (at 0x18) for our own purposes.
+	 * (E.g. sunxi-tools "fel" utility can pass information there.)
+	 */
+	union {
+		uint32_t header_size;
+		uint8_t spl_signature[4];
+	};
+	uint32_t fel_script_address;/* since v0.1, set by sunxi-fel */
+	/*
+	 * If the fel_uEnv_length member below is set to a non-zero value,
+	 * it specifies the size (byte count) of data at fel_script_address.
+	 * At the same time this indicates that the data is in uEnv.txt
+	 * compatible format, ready to be imported via "env import -t".
+	 */
+	uint32_t fel_uEnv_length;/* since v0.1, set by sunxi-fel */
+	/*
+	 * Offset of an ASCIIZ string (relative to the SPL header), which
+	 * contains the default device tree name (CONFIG_DEFAULT_DEVICE_TREE).
+	 * This is optional and may be set to NULL. Is intended to be used
+	 * by flash programming tools for providing nice informative messages
+	 * to the users.
+	 */
+	uint32_t dt_name_offset;/* since v0.2, set by mksunxiboot */
+	uint32_t dram_size;/* in MiB, since v0.3, set by SPL */
+	uint32_t boot_media;/* written here by the boot ROM */
+	/* A padding area (may be used for storing text strings) */
+	uint32_t string_pool[13];/* since v0.2, filled by mksunxiboot */
+	/* The header must be a multiple of 32 bytes (for VBAR alignment) */
+	/* And at least 64 byte (https://patchwork.ozlabs.org/patch/622173) */
+};
+#define EGON_HDR_BRANCH (0xea000000 | (sizeof(struct egon_header) / 4 - 2))
+#define sunxi_egon_header()						\
+	{								\
+		static const struct egon_header _hdr			\
+			__attribute__((section(".text_head_egon_header"))) = \
+			{ .branch = EGON_HDR_BRANCH, .magic = "eGON" };	\
+		__keep_symbolref(_hdr);					\
+	}
+
+#endif
diff --git a/scripts/Kconfig b/scripts/Kconfig
index dcd5f32d1d..7517f5b79f 100644
--- a/scripts/Kconfig
+++ b/scripts/Kconfig
@@ -56,6 +56,13 @@ config RK_IMAGE
 	help
 	  This enables building the image creation tool for Rockchip SoCs
 
+config EGON_IMAGE
+       bool "Allwinner eGON image tool" if COMPILE_HOST_TOOLS
+       depends on ARCH_SUNXI || COMPILE_HOST_TOOLS
+       default y if ARCH_SUNXI
+       help
+         This enables building the image creation tool for Allwinner sunxi SoCs
+
 config OMAP_IMAGE
 	bool "TI OMAP image tools" if COMPILE_HOST_TOOLS
 	depends on ARCH_OMAP || COMPILE_HOST_TOOLS
diff --git a/scripts/Makefile b/scripts/Makefile
index 72ad9ad7a6..13e80db7af 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -28,6 +28,7 @@ hostprogs-always-$(CONFIG_LAYERSCAPE_PBLIMAGE)		+= pblimage
 hostprogs-always-$(CONFIG_STM32_IMAGE)			+= stm32image
 hostprogs-always-$(CONFIG_RISCV)			+= prelink-riscv
 hostprogs-always-$(CONFIG_RK_IMAGE)			+= rkimage
+hostprogs-always-$(CONFIG_EGON_IMAGE)			+= egon_mkimage
 HOSTCFLAGS_rkimage = `pkg-config --cflags openssl`
 HOSTLDLIBS_rkimage = `pkg-config --libs openssl`
 KBUILD_HOSTCFLAGS += -I$(srctree)/scripts/include/
diff --git a/scripts/egon_mkimage.c b/scripts/egon_mkimage.c
new file mode 100644
index 0000000000..887caa29f0
--- /dev/null
+++ b/scripts/egon_mkimage.c
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "../include/mach/sunxi/egon.h"
+
+#include "compiler.h"
+#include "common.h"
+#include "common.c"
+
+#define ALIGN(x, a)		__ALIGN_MASK(x, (typeof(x))(a) - 1)
+#define __ALIGN_MASK(x, mask)	(((x) + (mask)) & ~(mask))
+#define STAMP_VALUE 0x5f0a6c39
+
+static void mkimage(char *infile, char *outfile)
+{
+	struct egon_header *hdr;
+	uint32_t *p32;
+	uint32_t sum;
+	int i;
+	size_t hdr_size;
+	size_t bin_size;
+	size_t img_size;
+	char *bin;
+	int fd, ret;
+
+	bin = read_file(infile, &bin_size);
+	if (!bin) {
+		perror("read_file");
+		exit(1);
+	}
+
+	/* the header must be a multiple of 32 bytes */
+	hdr_size = sizeof(*hdr);
+
+	/* test if the binary has reserved space for the header */
+	hdr = (void *)bin;
+	if (hdr->branch == EGON_HDR_BRANCH && memcmp(hdr->magic, "eGON", 4) == 0) {
+		/* strip the existing header */
+		bin += hdr_size;
+		bin_size -= hdr_size;
+	}
+	hdr = calloc(1, hdr_size);
+	if (!hdr) {
+		perror("malloc");
+		exit(1);
+	}
+
+	/* The total image length must be a multiple of 4K bytes */
+	img_size = ALIGN(hdr_size + bin_size, 4096);
+
+	hdr->check_sum = 0;
+	hdr->branch = EGON_HDR_BRANCH;
+	hdr->length = cpu_to_le32(img_size);
+	memcpy(hdr->magic, "eGON.BT0", 8);
+	memcpy(hdr->spl_signature, "SPL", 3);
+	hdr->spl_signature[3] = 0x03; /* version 0.3 */
+
+	/* calculate the checksum */
+	sum = STAMP_VALUE;
+	for (p32 = (void *) hdr, i = 0; i < hdr_size / sizeof(uint32_t); i++)
+		sum += le32_to_cpu(p32[i]);
+	for (p32 = (void *) bin, i = 0; i < bin_size / sizeof(uint32_t); i++)
+		sum += le32_to_cpu(p32[i]);
+	hdr->check_sum = cpu_to_le32(sum);
+
+	fd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT,
+		  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+	if (fd < 0) {
+		fprintf(stderr, "Cannot open %s: %s\n", outfile, strerror(errno));
+		exit(1);
+	}
+	/* write the header */
+	ret = write_full(fd, hdr, hdr_size);
+	if (ret < 0) {
+		perror("write_full");
+		exit(1);
+	}
+	/* write the binary */
+	ret = write_full(fd, bin, bin_size);
+	if (ret < 0) {
+		perror("write_full");
+		exit(1);
+	}
+	/* align the image */
+	ret = ftruncate(fd, img_size);
+	if (ret < 0) {
+		perror("ftruncate");
+		exit(1);
+	}
+	close(fd);
+
+	free(hdr);
+}
+
+static void usage(char *argv0)
+{
+	fprintf(stderr, "usage: %s <infile> <outfile>\n", argv0);
+}
+
+int main(int argc, char *argv[])
+{
+	if (argc != 3) {
+		usage(argv[0]);
+		return 1;
+	}
+
+	mkimage(argv[1], argv[2]);
+
+	return 0;
+}
-- 
2.40.0




  reply	other threads:[~2023-05-10 23:39 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-10 23:37 [RFC PATCH 00/11] Add support for Allwinner (sunxi) A64 SoC Jules Maselbas
2023-05-10 23:37 ` Jules Maselbas [this message]
2023-05-11  7:25   ` [RFC PATCH 01/11] scripts: Add Allwinner eGON image support Sascha Hauer
2023-05-11 20:14     ` Jules Maselbas
2023-05-18 18:47   ` Ahmad Fatoum
2023-05-19  9:40     ` Jules Maselbas
2023-05-10 23:37 ` [RFC PATCH 02/11] sunxi: introduce mach-sunxi Jules Maselbas
2023-05-11  7:27   ` Sascha Hauer
2023-05-18 18:46   ` Ahmad Fatoum
2023-05-19 10:09     ` Jules Maselbas
2023-05-22 10:32       ` Ahmad Fatoum
2023-05-10 23:37 ` [RFC PATCH 03/11] ARM: dls: Add ENTRY_HEADER macro to add .text section Jules Maselbas
2023-05-18 18:49   ` Ahmad Fatoum
2023-05-10 23:37 ` [RFC PATCH 04/11] sunxi: Add lowlevel switch to aarch64 Jules Maselbas
2023-05-18 19:01   ` Ahmad Fatoum
2023-05-10 23:37 ` [RFC PATCH 05/11] arm: sunxi: Add debug_ll Jules Maselbas
2023-05-18 19:05   ` Ahmad Fatoum
2023-05-19 10:36     ` Jules Maselbas
2023-05-10 23:37 ` [RFC PATCH 06/11] clk: Add clock driver for sun50i-a64 Jules Maselbas
2023-05-18 19:06   ` Ahmad Fatoum
2023-05-10 23:37 ` [RFC PATCH 07/11] pinctrl: Add sun50i-a64 pinctrl driver Jules Maselbas
2023-05-18 19:10   ` Ahmad Fatoum
2023-05-19 10:52     ` Jules Maselbas
2023-05-10 23:37 ` [RFC PATCH 08/11] mci: Add sunxi-mmc driver Jules Maselbas
2023-05-18 19:26   ` Ahmad Fatoum
2023-05-19  5:51     ` Sascha Hauer
2023-05-19  6:51       ` Ahmad Fatoum
2023-05-10 23:37 ` [RFC PATCH 09/11] arm: sunxi: Add sun50i SDRAM init Jules Maselbas
2023-05-11  7:39   ` Sascha Hauer
2023-05-10 23:37 ` [RFC PATCH 10/11] arm: boards: sunxi: Add initial support for the pinephone Jules Maselbas
2023-05-18 19:39   ` Ahmad Fatoum
2023-05-10 23:37 ` [RFC PATCH 11/11] arm: boards: sunxi: Add pine64 board Jules Maselbas
2023-05-18 19:44   ` Ahmad Fatoum
2023-05-19 16:30     ` Jules Maselbas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230510233711.37345-2-jmaselbas@zdiv.net \
    --to=jmaselbas@zdiv.net \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox