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

login
register
mail settings
Submitter Henrik Nordström
Date Nov. 25, 2012, 11:40 a.m.
Message ID <1353843650.17518.18.camel@home.hno.se>
Download mbox | patch
Permalink /patch/201523/
State Changes Requested
Delegated to: Albert ARIBAUD
Headers show

Comments

Henrik Nordström - Nov. 25, 2012, 11:40 a.m.
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
Luka Perkov - Nov. 25, 2012, 3:01 p.m.
Hi Henrik,

On Sun, Nov 25, 2012 at 12:40:50PM +0100, Henrik Nordström wrote:
> 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.

To use it:

$ ./mksunxiboot u-boot.bin u-boot-mmc.bin

Then you can write it to a mmc card with dd. For example if your mmc
card is located in /dev/sdb:

$ sudo dd if=u-boot-mmc.bin of=/dev/sdb bs=1024 seek=8

After inserting your mmc card into your A10 tablet it will boot from it.



Also, it would be nice to see more information here.

> 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

Please use a define on the top of file and use it here then.

> +	/* 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]);

You mean output_file, right ?

> +		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

Luka
Wolfgang Denk - Nov. 25, 2012, 5:47 p.m.
Dear Henrik Nordström,

In message <1353843650.17518.18.camel@home.hno.se> you wrote:
> 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.

Why do we need yet another "make file header" tool?  Why cannot this
be part of mkimage, for example?

Best regards,

Wolfgang Denk

Patch

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;
+}