[U-Boot] [PATCH 07/22] tools: mksunixboot adding a Allwinner boot header

Henrik Nordström
2012-11-25T11:40:50Z

This tool adds a boot header to the supplied file, for booting
code directly from the SoC embedded boot rom. Needed for making
the SPL loader bootable.

From: Tom Cubie <Mr.hipboi@gmail.com>
Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
Signed-off-by: Stefan Roese <sr@denx.de>
---
Makefile | 1 +
tools/.gitignore | 1 +
tools/Makefile | 6 ++
tools/mksunxiboot.README | 13 ++++
tools/mksunxiboot.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 183 insertions(+), 0 deletions(-)
create mode 100644 tools/mksunxiboot.README
create mode 100644 tools/mksunxiboot.c

diff --git a/Makefile b/Makefile
index 5a98745..81fe532 100644
--- a/Makefile
+++ b/Makefile
@@ -799,6 +799,7 @@ clean:
$(obj)tools/gen_eth_addr $(obj)tools/img2srec \
$(obj)tools/mk{env,}image $(obj)tools/mpc86x_clk \
$(obj)tools/mk{smdk5250,}spl \
+ $(obj)tools/mksunxiboot \
$(obj)tools/mxsboot \
$(obj)tools/ncb $(obj)tools/ubsha1 \
$(obj)tools/kernel-doc/docproc
diff --git a/tools/.gitignore b/tools/.gitignore
index 9bce719..92fcbbd 100644
--- a/tools/.gitignore
+++ b/tools/.gitignore
@@ -7,6 +7,7 @@
/mkimage
/mpc86x_clk
/mxsboot
+/mksunxiboot
/ncb
/ncp
/ubsha1
diff --git a/tools/Makefile b/tools/Makefile
index 686840a..508112d 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -69,6 +69,7 @@ BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX)
BIN_FILES-y += mkenvimage$(SFX)
BIN_FILES-y += mkimage$(SFX)
BIN_FILES-$(CONFIG_SMDK5250) += mksmdk5250spl$(SFX)
+BIN_FILES-$(CONFIG_SUNXI) += mksunxiboot$(SFX)
BIN_FILES-$(CONFIG_MX28) += mxsboot$(SFX)
BIN_FILES-$(CONFIG_NETCONSOLE) += ncb$(SFX)
BIN_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1$(SFX)
@@ -98,6 +99,7 @@ NOPED_OBJ_FILES-y += omapimage.o
NOPED_OBJ_FILES-y += mkenvimage.o
NOPED_OBJ_FILES-y += mkimage.o
OBJ_FILES-$(CONFIG_SMDK5250) += mkexynosspl.o
+OBJ_FILES-$(CONFIG_SUNXI) += mksunxiboot.o
OBJ_FILES-$(CONFIG_MX28) += mxsboot.o
OBJ_FILES-$(CONFIG_NETCONSOLE) += ncb.o
NOPED_OBJ_FILES-y += os_support.o
@@ -228,6 +230,10 @@ $(obj)mpc86x_clk$(SFX): $(obj)mpc86x_clk.o
$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
$(HOSTSTRIP) $@

+$(obj)mksunxiboot$(SFX): $(obj)mksunxiboot.o
+ $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+ $(HOSTSTRIP) $@
+
$(obj)mxsboot$(SFX): $(obj)mxsboot.o
$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
$(HOSTSTRIP) $@
diff --git a/tools/mksunxiboot.README b/tools/mksunxiboot.README
new file mode 100644
index 0000000..9a4b379
--- /dev/null
+++ b/tools/mksunxiboot.README
@@ -0,0 +1,13 @@
+This program make a arm binary file can be loaded by Allwinner A10 and releated
+chips from storage media such as nand and mmc.
+
+More information about A10 boot, please refer to
+http://rhombus-tech.net/allwinner_a10/a10_boot_process/
+
+To compile this program, just type make, you will get 'mksunxiboot'.
+
+To use it,
+$./mksunxiboot u-boot.bin u-boot-mmc.bin
+then you can write it to a mmc card with dd.
+$sudo dd if=u-boot-mmc.bin of=/dev/sdb bs=1024 seek=8
+then insert your mmc card to your A10 tablet, you can boot from mmc card.
diff --git a/tools/mksunxiboot.c b/tools/mksunxiboot.c
new file mode 100644
index 0000000..fd81529
--- /dev/null
+++ b/tools/mksunxiboot.c
@@ -0,0 +1,162 @@
+/*
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * a simple tool to generate bootable image for sunxi platform.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+typedef unsigned char u8;
+typedef unsigned int u32;
+
+/* boot head definition from sun4i boot code */
+typedef struct boot_file_head {
+ u32 jump_instruction; /* one intruction jumping to real code */
+ u8 magic[8]; /* ="eGON.BT0" or "eGON.BT1", not C-style str */
+ u32 check_sum; /* generated by PC */
+ u32 length; /* generated by PC */
+#if 1
+ /* We use a simplified header, only filling in what is needed by the
+ * boot ROM. To be compatible with Allwinner tools the larger header
+ * below should be used, followed by a custom header if desired. */
+ u8 pad[12]; /* align to 32 bytes */
+#else
+ u32 pub_head_size; /* the size of boot_file_head_t */
+ u8 pub_head_vsn[4]; /* the version of boot_file_head_t */
+ u8 file_head_vsn[4]; /* the version of boot0_file_head_t or
+ boot1_file_head_t */
+ u8 Boot_vsn[4]; /* Boot version */
+ u8 eGON_vsn[4]; /* eGON version */
+ u8 platform[8]; /* platform information */
+#endif
+} boot_file_head_t;
+
+#define BOOT0_MAGIC "eGON.BT0"
+#define STAMP_VALUE 0x5F0A6C39
+
+/* check sum functon from sun4i boot code */
+int gen_check_sum(void *boot_buf)
+{
+ boot_file_head_t *head_p;
+ u32 length;
+ u32 *buf;
+ u32 loop;
+ u32 i;
+ u32 sum;
+
+ head_p = (boot_file_head_t *) boot_buf;
+ length = head_p->length;
+ if ((length & 0x3) != 0) /* must 4-byte-aligned */
+ return -1;
+ buf = (u32 *) boot_buf;
+ head_p->check_sum = STAMP_VALUE; /* fill stamp */
+ loop = length >> 2;
+
+ /* calculate the sum */
+ for (i = 0, sum = 0; i < loop; i++)
+ sum += buf[i];
+
+ /* write back check sum */
+ head_p->check_sum = sum;
+
+ return 0;
+}
+
+#define ALIGN(x, a) __ALIGN_MASK((x), (typeof(x))(a)-1)
+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
+
+#define SUN4I_SRAM_SIZE (24 * 1024)
+#define SRAM_LOAD_MAX_SIZE (SUN4I_SRAM_SIZE - sizeof(boot_file_head_t))
+#define BLOCK_SIZE 512
+
+struct boot_img {
+ boot_file_head_t header;
+ char code[SRAM_LOAD_MAX_SIZE];
+ char pad[BLOCK_SIZE];
+};
+
+int main(int argc, char *argv[])
+{
+ int fd_in, fd_out;
+ struct boot_img img;
+ unsigned file_size, load_size;
+ int count;
+
+ if (argc < 2) {
+ printf
+ ("\tThis program makes an input bin file to sun4i bootable image.\n"
+ "\tUsage: %s input_file out_putfile\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ fd_in = open(argv[1], O_RDONLY);
+ if (fd_in < 0) {
+ perror("Open input file:");
+ return EXIT_FAILURE;
+ }
+
+ fd_out = open(argv[2], O_WRONLY | O_CREAT, 0666);
+ if (fd_out < 0) {
+ perror("Open output file:");
+ return EXIT_FAILURE;
+ }
+
+ memset((void *)img.pad, 0, BLOCK_SIZE);
+
+ /* get input file size */
+ file_size = lseek(fd_in, 0, SEEK_END);
+ printf("File size: 0x%x\n", file_size);
+
+ if (file_size > SRAM_LOAD_MAX_SIZE)
+ load_size = SRAM_LOAD_MAX_SIZE;
+ else
+ load_size = ALIGN(file_size, sizeof(int));
+ printf("Load size: 0x%x\n", load_size);
+
+ /* read file to buffer to calculate checksum */
+ lseek(fd_in, 0, SEEK_SET);
+ count = read(fd_in, img.code, load_size);
+ printf("Read 0x%x bytes\n", count);
+
+ /* fill the header */
+ img.header.jump_instruction = /* b instruction */
+ 0xEA000000 | /* jump to the first instr after the header */
+ ((sizeof(boot_file_head_t) / sizeof(int) - 2)
+ & 0x00FFFFFF);
+ memcpy(img.header.magic, BOOT0_MAGIC, 8); /* no '0' termination */
+ img.header.length =
+ ALIGN(load_size + sizeof(boot_file_head_t), BLOCK_SIZE);
+ gen_check_sum((void *)&img);
+
+ count = write(fd_out, (void *)&img, img.header.length);
+ printf("Write 0x%x bytes\n", count);
+
+ close(fd_in);
+ close(fd_out);
+
+ return EXIT_SUCCESS;
+}
--
1.7.7.6