summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2019-07-12 07:10:18 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2019-07-12 07:10:18 +0200
commitca1c1456a16ee50f60f53e4efda04b310372a9b7 (patch)
tree02a289570992a3acb951841709741cdb4bbf0ade
parent5ed435f33dc6a31cd93b6f38a14dd775977cf1cc (diff)
parent8a16615f9efe7e0f94c6c8132c0df4e3ad0d7f44 (diff)
downloadbarebox-ca1c1456a16ee50f60f53e4efda04b310372a9b7.tar.gz
barebox-ca1c1456a16ee50f60f53e4efda04b310372a9b7.tar.xz
Merge branch 'for-next/mvebu'
-rw-r--r--arch/arm/boards/globalscale-mirabox/kwbimage.cfg5
-rw-r--r--arch/arm/boards/lenovo-ix4-300d/kwbimage.cfg5
-rw-r--r--arch/arm/boards/marvell-armada-xp-db/kwbimage.cfg3
-rw-r--r--arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg3
-rw-r--r--arch/arm/boards/netgear-rn104/kwbimage.cfg7
-rw-r--r--arch/arm/boards/netgear-rn2120/kwbimage.cfg7
-rw-r--r--arch/arm/boards/plathome-openblocks-ax3/kwbimage.cfg3
-rw-r--r--arch/arm/boards/turris-omnia/kwbimage.cfg7
-rw-r--r--images/Makefile.mvebu93
-rw-r--r--scripts/Makefile2
-rw-r--r--scripts/Makefile.lib3
-rw-r--r--scripts/mvebuimg.c569
12 files changed, 630 insertions, 77 deletions
diff --git a/arch/arm/boards/globalscale-mirabox/kwbimage.cfg b/arch/arm/boards/globalscale-mirabox/kwbimage.cfg
deleted file mode 100644
index fa8e5a6ee4..0000000000
--- a/arch/arm/boards/globalscale-mirabox/kwbimage.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-VERSION 1
-BOOT_FROM nand
-NAND_BLKSZ 00020000
-NAND_BADBLK_LOCATION 01
-BINARY ./binary.0 0000005b 00000068
diff --git a/arch/arm/boards/lenovo-ix4-300d/kwbimage.cfg b/arch/arm/boards/lenovo-ix4-300d/kwbimage.cfg
deleted file mode 100644
index a9b035e113..0000000000
--- a/arch/arm/boards/lenovo-ix4-300d/kwbimage.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-VERSION 1
-BOOT_FROM nand
-NAND_BLKSZ 00020000
-NAND_BADBLK_LOCATION 00
-BINARY ./binary.0 0000005b 00000068
diff --git a/arch/arm/boards/marvell-armada-xp-db/kwbimage.cfg b/arch/arm/boards/marvell-armada-xp-db/kwbimage.cfg
deleted file mode 100644
index 28e60e2f18..0000000000
--- a/arch/arm/boards/marvell-armada-xp-db/kwbimage.cfg
+++ /dev/null
@@ -1,3 +0,0 @@
-VERSION 1
-BOOT_FROM uart
-BINARY ./binary.0 0000005b 00000000
diff --git a/arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg b/arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg
deleted file mode 100644
index eb8a2e7aed..0000000000
--- a/arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg
+++ /dev/null
@@ -1,3 +0,0 @@
-VERSION 1
-BOOT_FROM spi
-BINARY ./binary.0 0000005b 00000068
diff --git a/arch/arm/boards/netgear-rn104/kwbimage.cfg b/arch/arm/boards/netgear-rn104/kwbimage.cfg
deleted file mode 100644
index 83a4149053..0000000000
--- a/arch/arm/boards/netgear-rn104/kwbimage.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-VERSION 1
-BOOT_FROM nand
-DESTADDR 00600000
-EXECADDR 006a0000
-NAND_BLKSZ 00020000
-NAND_BADBLK_LOCATION 01
-BINARY binary.0 0000005b 00000068
diff --git a/arch/arm/boards/netgear-rn2120/kwbimage.cfg b/arch/arm/boards/netgear-rn2120/kwbimage.cfg
deleted file mode 100644
index a6f0aa6d3d..0000000000
--- a/arch/arm/boards/netgear-rn2120/kwbimage.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-VERSION 1
-BOOT_FROM nand
-DESTADDR 00000000
-EXECADDR 00000000
-NAND_BLKSZ 00020000
-NAND_BADBLK_LOCATION 01
-BINARY binary.0 0000005b 00000068
diff --git a/arch/arm/boards/plathome-openblocks-ax3/kwbimage.cfg b/arch/arm/boards/plathome-openblocks-ax3/kwbimage.cfg
deleted file mode 100644
index eb8a2e7aed..0000000000
--- a/arch/arm/boards/plathome-openblocks-ax3/kwbimage.cfg
+++ /dev/null
@@ -1,3 +0,0 @@
-VERSION 1
-BOOT_FROM spi
-BINARY ./binary.0 0000005b 00000068
diff --git a/arch/arm/boards/turris-omnia/kwbimage.cfg b/arch/arm/boards/turris-omnia/kwbimage.cfg
deleted file mode 100644
index 789ee5df17..0000000000
--- a/arch/arm/boards/turris-omnia/kwbimage.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-VERSION 1
-BOOT_FROM spi
-DESTADDR 00800000
-EXECADDR 00800000
-NAND_BLKSZ 00000000
-NAND_BADBLK_LOCATION 00
-BINARY binary.0 0000005b 00000068
diff --git a/images/Makefile.mvebu b/images/Makefile.mvebu
index 846dd46095..112227424b 100644
--- a/images/Makefile.mvebu
+++ b/images/Makefile.mvebu
@@ -7,78 +7,95 @@
$(obj)/%.kwbimg: $(obj)/% FORCE
$(call if_changed,kwb_image)
+$(obj)/%.mvebu0img: $(obj)/% scripts/mvebuimg FORCE
+ $(call if_changed,mvebu0_image)
+
+$(obj)/%.mvebu1img: $(obj)/% scripts/mvebuimg FORCE
+ $(call if_changed,mvebu1_image)
+
KWBOPTS = -c -d 0x1000000 -e 0x1000000
# ----------------------- Armada 370 based boards ---------------------------
-GLOBALSCALE_MIRABOX_KWBOPTS = ${KWBOPTS} -i $(board)/globalscale-mirabox/kwbimage.cfg
-OPTS_start_globalscale_mirabox.pblb.kwbimg = $(GLOBALSCALE_MIRABOX_KWBOPTS)
-FILE_barebox-globalscale-mirabox.img = start_globalscale_mirabox.pblb.kwbimg
-FILE_barebox-globalscale-mirabox-2nd.img = start_globalscale_mirabox.pblb
+BOOTSRC_start_globalscale_mirabox.pblb.mvebu1img = nand
+BINHDR_start_globalscale_mirabox.pblb.mvebu1img = $(board)/globalscale-mirabox/binary.0
+FLAGS_start_globalscale_mirabox.pblb.mvebu1img = -B 0x20000:1
+FILE_barebox-globalscale-mirabox.img = start_globalscale_mirabox.pblb.mvebu1img
pblb-$(CONFIG_MACH_GLOBALSCALE_MIRABOX) += start_globalscale_mirabox
image-$(CONFIG_MACH_GLOBALSCALE_MIRABOX) += barebox-globalscale-mirabox.img
+
+FILE_barebox-globalscale-mirabox-2nd.img = start_globalscale_mirabox.pblb
image-$(CONFIG_MACH_GLOBALSCALE_MIRABOX) += barebox-globalscale-mirabox-2nd.img
-NETGEAR_RN104_KWBOPTS = ${KWBOPTS} -i $(board)/netgear-rn104/kwbimage.cfg
-OPTS_start_netgear_rn104.pblb.kwbimg = $(NETGEAR_RN104_KWBOPTS)
-FILE_barebox-netgear-rn104.img = start_netgear_rn104.pblb.kwbimg
-FILE_barebox-netgear-rn104-2nd.img = start_netgear_rn104.pblb
+FLAGS_start_netgear_rn104.pblb.mvebu1img = -d 0x600000 -e 0x6e0000
+BOOTSRC_start_netgear_rn104.pblb.mvebu1img = nand
+BINHDR_start_netgear_rn104.pblb.mvebu1img = $(board)/netgear-rn104/binary.0
+FLAGS_start_netgear_rn104.pblb.mvebu1img = -B 0x20000:1
+FILE_barebox-netgear-rn104.img = start_netgear_rn104.pblb.mvebu1img
pblb-$(CONFIG_MACH_NETGEAR_RN104) += start_netgear_rn104
image-$(CONFIG_MACH_NETGEAR_RN104) += barebox-netgear-rn104.img
+
+FILE_barebox-netgear-rn104-2nd.img = start_netgear_rn104.pblb
image-$(CONFIG_MACH_NETGEAR_RN104) += barebox-netgear-rn104-2nd.img
# ----------------------- Armada XP based boards ---------------------------
-LENOVO_IX4_300D_KWBOPTS = ${KWBOPTS} -i $(board)/lenovo-ix4-300d/kwbimage.cfg
-OPTS_start_lenovo_ix4_300d.pblb.kwbimg = $(LENOVO_IX4_300D_KWBOPTS)
-FILE_barebox-lenovo-ix4-300d.img = start_lenovo_ix4_300d.pblb.kwbimg
-FILE_barebox-lenovo-ix4-300d-2nd.img = start_lenovo_ix4_300d.pblb
+BOOTSRC_start_lenovo_ix4_300d.pblb.mvebu1img = nand
+BINHDR_start_lenovo_ix4_300d.pblb.mvebu1img = $(board)/lenovo-ix4-300d/binary.0
+FLAGS_start_lenovo_ix4_300d.pblb.mvebu1img = -B 0x20000:0
+FILE_barebox-lenovo-ix4-300d.img = start_lenovo_ix4_300d.pblb.mvebu1img
pblb-$(CONFIG_MACH_LENOVO_IX4_300D) += start_lenovo_ix4_300d
image-$(CONFIG_MACH_LENOVO_IX4_300D) += barebox-lenovo-ix4-300d.img
+
+FILE_barebox-lenovo-ix4-300d-2nd.img = start_lenovo_ix4_300d.pblb
image-$(CONFIG_MACH_LENOVO_IX4_300D) += barebox-lenovo-ix4-300d-2nd.img
-MARVELL_ARMADA_XP_GP_KWBOPTS = ${KWBOPTS} -i $(board)/marvell-armada-xp-gp/kwbimage.cfg
-OPTS_start_marvell_armada_xp_gp.pblb.kwbimg = $(MARVELL_ARMADA_XP_GP_KWBOPTS)
-FILE_barebox-marvell-armada-xp-gp.img = start_marvell_armada_xp_gp.pblb.kwbimg
-FILE_barebox-marvell-armada-xp-gp-2nd.img = start_marvell_armada_xp_gp.pblb
+BOOTSRC_start_marvell_armada_xp_gp.pblb.mvebu1img = spi
+BINHDR_start_marvell_armada_xp_gp.pblb.mvebu1img = $(board)/marvell-armada-xp-gp/binary.0
+FILE_barebox-marvell-armada-xp-gp.img = start_marvell_armada_xp_gp.pblb.mvebu1img
pblb-$(CONFIG_MACH_MARVELL_ARMADA_XP_GP) += start_marvell_armada_xp_gp
image-$(CONFIG_MACH_MARVELL_ARMADA_XP_GP) += barebox-marvell-armada-xp-gp.img
+
+FILE_barebox-marvell-armada-xp-gp-2nd.img = start_marvell_armada_xp_gp.pblb
image-$(CONFIG_MACH_MARVELL_ARMADA_XP_GP) += barebox-marvell-armada-xp-gp-2nd.img
-MARVELL_ARMADA_XP_DB_KWBOPTS = ${KWBOPTS} -i $(board)/marvell-armada-xp-db/kwbimage.cfg
-OPTS_start_marvell_armada_xp_db.pblb.kwbimg = $(MARVELL_ARMADA_XP_DB_KWBOPTS)
-FILE_barebox-marvell-armada-xp-db.img = start_marvell_armada_xp_db.pblb.kwbimg
-FILE_barebox-marvell-armada-xp-db-2nd.img = start_marvell_armada_xp_db.pblb
+BOOTSRC_start_marvell_armada_xp_db.pblb.mvebu1img = uart
+BINHDR_start_marvell_armada_xp_db.pblb.mvebu1img = $(board)/marvell-armada-xp-db/binary.0
+FILE_barebox-marvell-armada-xp-db.img = start_marvell_armada_xp_db.pblb.mvebu1img
pblb-$(CONFIG_MACH_MARVELL_ARMADA_XP_DB) += start_marvell_armada_xp_db
image-$(CONFIG_MACH_MARVELL_ARMADA_XP_DB) += barebox-marvell-armada-xp-db.img
+
+FILE_barebox-marvell-armada-xp-db-2nd.img = start_marvell_armada_xp_db.pblb
image-$(CONFIG_MACH_MARVELL_ARMADA_XP_DB) += barebox-marvell-armada-xp-db-2nd.img
-NETGEAR_RN2120_KWBOPTS = ${KWBOPTS} -i $(board)/netgear-rn2120/kwbimage.cfg
-OPTS_start_netgear_rn2120.pblb.kwbimg = $(NETGEAR_RN2120_KWBOPTS)
-FILE_barebox-netgear-rn2120.img = start_netgear_rn2120.pblb.kwbimg
-FILE_barebox-netgear-rn2120-2nd.img = start_netgear_rn2120.pblb
+BOOTSRC_start_netgear_rn2120.pblb.mvebu1img = nand
+BINHDR_start_netgear_rn2120.pblb.mvebu1img = $(board)/netgear-rn2120/binary.0
+FLAGS_start_netgear_rn2120.pblb.mvebu1img = -B 0x20000:1
+FILE_barebox-netgear-rn2120.img = start_netgear_rn2120.pblb.mvebu1img
pblb-$(CONFIG_MACH_NETGEAR_RN2120) += start_netgear_rn2120
image-$(CONFIG_MACH_NETGEAR_RN2120) += barebox-netgear-rn2120.img
+
+FILE_barebox-netgear-rn2120-2nd.img = start_netgear_rn2120.pblb
image-$(CONFIG_MACH_NETGEAR_RN2120) += barebox-netgear-rn2120-2nd.img
# ----------------------- Armada 38x based boards ---------------------------
-TURRIS_OMNIA_KWBOPTS = ${KWBOPTS} -i $(board)/turris-omnia/kwbimage.cfg
-OPTS_start_turris_omnia.pblb.kwbimg = $(TURRIS_OMNIA_KWBOPTS)
-FILE_barebox-turris-omnia.img = start_turris_omnia.pblb.kwbimg
-FILE_barebox-turris-omnia-2nd.img = start_turris_omnia.pblb
+BOOTSRC_start_turris_omnia.pblb.mvebu1img = spi
+BINHDR_start_turris_omnia.pblb.mvebu1img = $(board)/turris-omnia/binary.0
+FILE_barebox-turris-omnia.img = start_turris_omnia.pblb.mvebu1img
pblb-$(CONFIG_MACH_TURRIS_OMNIA) += start_turris_omnia
image-$(CONFIG_MACH_TURRIS_OMNIA) += barebox-turris-omnia.img
-PLATHOME_OPENBLOCKS_AX3_KWBOPTS = ${KWBOPTS} -i $(board)/plathome-openblocks-ax3/kwbimage.cfg
-OPTS_start_plathome_openblocks_ax3.pblb.kwbimg = $(PLATHOME_OPENBLOCKS_AX3_KWBOPTS)
-FILE_barebox-plathome-openblocks-ax3.img = start_plathome_openblocks_ax3.pblb.kwbimg
-FILE_barebox-plathome-openblocks-ax3-2nd.img = start_plathome_openblocks_ax3.pblb
+BOOTSRC_start_plathome_openblocks_ax3.pblb.mvebu1img = spi
+BINHDR_start_plathome_openblocks_ax3.pblb.mvebu1img = $(board)/plathome-openblocks-ax3/binary.0
+FILE_barebox-plathome-openblocks-ax3.img = start_plathome_openblocks_ax3.pblb.mvebu1img
pblb-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3) += start_plathome_openblocks_ax3
image-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3) += barebox-plathome-openblocks-ax3.img
+
+FILE_barebox-plathome-openblocks-ax3-2nd.img = start_plathome_openblocks_ax3.pblb
image-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3) += barebox-plathome-openblocks-ax3-2nd.img
# ----------------------- Dove 88AP510 based boards ---------------------------
SOLIDRUN_CUBOX_KWBOPTS = ${KWBOPTS} -i $(board)/solidrun-cubox/kwbimage.cfg
OPTS_start_solidrun_cubox.pblb.kwbimg = $(SOLIDRUN_CUBOX_KWBOPTS)
-FILE_barebox-solidrun-cubox.img = start_solidrun_cubox.pblb.kwbimg
+FILE_barebox-solidrun-cubox.img = start_solidrun_cubox.pblb.kwbimg
FILE_barebox-solidrun-cubox-2nd.img = start_solidrun_cubox.pblb
pblb-$(CONFIG_MACH_SOLIDRUN_CUBOX) += start_solidrun_cubox
image-$(CONFIG_MACH_SOLIDRUN_CUBOX) += barebox-solidrun-cubox.img
@@ -87,7 +104,7 @@ image-$(CONFIG_MACH_SOLIDRUN_CUBOX) += barebox-solidrun-cubox-2nd.img
# ----------------------- Kirkwood based boards ---------------------------
GLOBALSCALE_GURUPLUG_KWBOPTS = ${KWBOPTS} -i $(board)/globalscale-guruplug/kwbimage.cfg
OPTS_start_globalscale_guruplug.pblb.kwbimg = $(GLOBALSCALE_GURUPLUG_KWBOPTS)
-FILE_barebox-globalscale-guruplug.img = start_globalscale_guruplug.pblb.kwbimg
+FILE_barebox-globalscale-guruplug.img = start_globalscale_guruplug.pblb.kwbimg
FILE_barebox-globalscale-guruplug-2nd.img = start_globalscale_guruplug.pblb
pblb-$(CONFIG_MACH_GLOBALSCALE_GURUPLUG) += start_globalscale_guruplug
image-$(CONFIG_MACH_GLOBALSCALE_GURUPLUG) += barebox-globalscale-guruplug.img
@@ -95,7 +112,7 @@ image-$(CONFIG_MACH_GLOBALSCALE_GURUPLUG) += barebox-globalscale-guruplug-2nd.im
PLATHOME_OPENBLOCKS_A6_KWBOPTS = ${KWBOPTS} -i $(board)/plathome-openblocks-a6/kwbimage.cfg
OPTS_start_plathome_openblocks_a6.pblb.kwbimg = $(PLATHOME_OPENBLOCKS_A6_KWBOPTS)
-FILE_barebox-plathome-openblocks-a6.img = start_plathome_openblocks_a6.pblb.kwbimg
+FILE_barebox-plathome-openblocks-a6.img = start_plathome_openblocks_a6.pblb.kwbimg
FILE_barebox-plathome-openblocks-a6-2nd.img = start_plathome_openblocks_a6.pblb
pblb-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_A6) += start_plathome_openblocks_a6
image-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_A6) += barebox-plathome-openblocks-a6.img
@@ -103,8 +120,12 @@ image-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_A6) += barebox-plathome-openblocks-a6-2n
USI_TOPKICK_KWBOPTS = ${KWBOPTS} -i $(board)/usi-topkick/kwbimage.cfg
OPTS_start_usi_topkick.pblb.kwbimg = $(USI_TOPKICK_KWBOPTS)
-FILE_barebox-usi-topkick.img = start_usi_topkick.pblb.kwbimg
+FILE_barebox-usi-topkick.img = start_usi_topkick.pblb.kwbimg
FILE_barebox-usi-topkick-2nd.img = start_usi_topkick.pblb
pblb-$(CONFIG_MACH_USI_TOPKICK) += start_usi_topkick
image-$(CONFIG_MACH_USI_TOPKICK) += barebox-usi-topkick.img
image-$(CONFIG_MACH_USI_TOPKICK) += barebox-usi-topkick-2nd.img
+
+# ensure that an image depends on its included binhdrs
+$(foreach f,$(pblb-y),$(eval $$(obj)/$f.pblb.mvebu0img: $$(BINHDR_$f.pblb.mvebu0img)))
+$(foreach f,$(pblb-y),$(eval $$(obj)/$f.pblb.mvebu1img: $$(BINHDR_$f.pblb.mvebu1img)))
diff --git a/scripts/Makefile b/scripts/Makefile
index 1af5f9fc98..7d64da6b55 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -13,7 +13,7 @@ hostprogs-y += kernel-install
hostprogs-$(CONFIG_IMD) += bareboximd
hostprogs-$(CONFIG_KALLSYMS) += kallsyms
hostprogs-$(CONFIG_MIPS) += mips-relocs
-hostprogs-$(CONFIG_MVEBU_HOSTTOOLS) += kwbimage kwboot
+hostprogs-$(CONFIG_MVEBU_HOSTTOOLS) += kwbimage kwboot mvebuimg
hostprogs-$(CONFIG_ARCH_NETX) += gen_netx_image
hostprogs-$(CONFIG_ARCH_OMAP) += omap_signGP mk-omap-image
hostprogs-$(CONFIG_ARCH_S5PCxx) += s5p_cksum
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 87bff2d296..75e1734f79 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -503,6 +503,9 @@ quiet_cmd_imx_image = IMX-IMG $@
quiet_cmd_kwb_image = KWB $@
cmd_kwb_image = scripts/kwbimage -p $< $(OPTS_$(@F)) -o $@
+quiet_cmd_mvebu1_image = MVIMG $@
+ cmd_mvebu1_image = scripts/mvebuimg -v 1 create -o $@ $(foreach b,$(BINHDR_$(@F)),-b $b) $(FLAGS_$(@F)) $(BOOTSRC_$(@F)) $<
+
quiet_cmd_cboot_bct = BCT $@
cmd_cboot_bct = $(objtree)/scripts/tegra/cbootimage -gbct -s $(soc) $< $@
diff --git a/scripts/mvebuimg.c b/scripts/mvebuimg.c
new file mode 100644
index 0000000000..8e9b1f9112
--- /dev/null
+++ b/scripts/mvebuimg.c
@@ -0,0 +1,569 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define ALIGN_SUP(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#define is_power_of_two(a) (((a) & ((a) - 1)) == 0)
+#define container_of(ptr, type, member) \
+ (type *)((char *)(ptr) - (char *) &((type *)0)->member)
+
+
+#define pr_err(fmt, arg...) fprintf(stderr, "ERROR: " fmt, ##arg)
+#define pr_info(fmt, arg...) fprintf(stderr, "INFO: " fmt, ##arg)
+
+static const struct {
+ unsigned char id;
+ char *name;
+} boot_ids[] = {
+ { 0x4d, "i2c" },
+ { 0x5a, "spi" },
+ { 0x69, "uart" },
+ { 0x78, "sata" },
+ { 0x8b, "nand" },
+ { 0x9c, "pex" },
+ { /* sentinel */ }
+};
+
+struct mvebuimg_checksum_method {
+ void (*update)(struct mvebuimg_checksum_method *self,
+ const void *buf, size_t len);
+};
+
+struct mvebuimg_checksum_method8 {
+ struct mvebuimg_checksum_method method;
+ uint8_t csum;
+};
+
+static void mvebuimg_checksum8(struct mvebuimg_checksum_method *self,
+ const void *buf, size_t len)
+{
+ struct mvebuimg_checksum_method8 *realself =
+ container_of(self, struct mvebuimg_checksum_method8, method);
+
+ while (len--) {
+ realself->csum += *(uint8_t *)buf;
+ buf++;
+ }
+}
+
+struct mvebuimg_checksum_method32 {
+ struct mvebuimg_checksum_method method;
+ uint32_t csum;
+ int mod;
+};
+
+static void mvebuimg_checksum32(struct mvebuimg_checksum_method *self,
+ const void *buf, size_t len)
+{
+ struct mvebuimg_checksum_method32 *realself =
+ container_of(self, struct mvebuimg_checksum_method32, method);
+
+ while (len--) {
+ realself->csum += *(uint8_t *)buf << (8 * realself->mod);
+ realself->mod = (realself->mod + 1) % 4;
+ buf++;
+ }
+}
+
+static ssize_t mvebuimg_sendfile(int outfd, int infd,
+ struct mvebuimg_checksum_method *csumm,
+ size_t count)
+{
+ char buf[1024];
+ size_t head = 0, tail = 0;
+ int ret;
+ size_t count_read = 0, count_written = 0;
+
+ while (count_written < count) {
+ if (head == tail) {
+ head = 0;
+ tail = 0;
+ }
+
+ if (tail < sizeof(buf) && count_read < count) {
+ ret = read(infd, buf + tail,
+ min(count, sizeof(buf) - tail));
+ if (ret < 0) {
+ pr_err("read error\n");
+ return ret;
+ }
+
+ if (ret == 0) {
+ pr_err("hit EOF\n");
+ return -EINVAL;
+ }
+
+ if (csumm)
+ csumm->update(csumm, buf + tail, ret);
+
+ tail += ret;
+ count_read += ret;
+ }
+
+ if (head < tail) {
+ ret = write(outfd, buf + head, tail - head);
+ if (ret < 0)
+ return ret;
+
+ head += ret;
+ count_written += ret;
+ }
+ }
+
+ return 0;
+}
+
+static int mvebuimg_v1_write_binhdr(int fd, size_t *offset,
+ const char *filename,
+ struct mvebuimg_checksum_method8 *summ,
+ int is_last_header)
+{
+ int binhdr_fd;
+ char binhdr[16] = { 0, };
+ struct stat s;
+ uint32_t hdrsize;
+ int ret;
+ off_t ret_lseek;
+ char trailer[4] = { 0, };
+
+ binhdr[0] = 0x2;
+
+ binhdr_fd = open(filename, O_RDONLY);
+ if (binhdr_fd < 0) {
+ pr_err("Failed to open binhdr source \"%s\" (%s)\n",
+ filename, strerror(errno));
+ return -errno;
+ }
+
+ ret = fstat(binhdr_fd, &s);
+ if (ret < 0) {
+ pr_err("Failed to stat binhdr source \"%s\" (%s)\n",
+ filename, strerror(errno));
+ return -errno;
+ }
+
+ if (ALIGN_SUP(s.st_size, 4) > 0xffffff - 0x14) {
+ pr_err("binhdr \"%s\" too big\n", filename);
+ return -EINVAL;
+ }
+
+ hdrsize = /* len of hdr's header */ 0x10 +
+ /* actual image */ ALIGN_SUP(s.st_size, 4) +
+ /* trailer word */ 4;
+
+ binhdr[1] = hdrsize >> 16;
+ binhdr[2] = hdrsize;
+ binhdr[3] = hdrsize >> 8;
+
+ /* parameters that are used by all images I know of */
+ binhdr[4] = 2;
+ binhdr[8] = 0x5b;
+ binhdr[12] = 0x68;
+
+ summ->method.update(&summ->method, binhdr, sizeof(binhdr));
+ ret = pwrite(fd, binhdr, sizeof(binhdr), *offset);
+ if (ret < 0) {
+ pr_err("failed to write header of binhdr \"%s\"\n",
+ filename);
+ return -errno;
+ }
+
+ *offset += sizeof(binhdr);
+
+ ret_lseek = lseek(fd, *offset, SEEK_SET);
+ if (ret_lseek == (off_t)-1) {
+ pr_err("failed to seek to binhdr offset\n");
+ return -errno;
+ }
+
+ ret = mvebuimg_sendfile(fd, binhdr_fd, &summ->method, s.st_size);
+ if (ret < 0)
+ return ret;
+
+ *offset += ALIGN_SUP(s.st_size, 4);
+ trailer[0] = is_last_header ? 0 : 1;
+
+ summ->method.update(&summ->method, trailer, sizeof(4));
+ ret = pwrite(fd, trailer, sizeof(trailer), *offset);
+ if (ret < 0) {
+ pr_err("failed to write trailer of binhdr \"%s\"\n",
+ filename);
+ return -errno;
+ }
+
+ *offset += 4;
+
+ return 0;
+}
+
+static int mvebuimg_v1_write_payload(int fd, size_t *offset,
+ const char *filename)
+{
+ int payload_fd;
+ struct stat s;
+ int ret;
+ char pad[4] = { 0, };
+ struct mvebuimg_checksum_method32 csumm32 = {
+ .method = {
+ .update = mvebuimg_checksum32,
+ },
+ .csum = 0,
+ };
+
+ payload_fd = open(filename, O_RDONLY);
+ if (payload_fd < 0) {
+ pr_err("Failed to open payload \"%s\" (%s)\n",
+ filename, strerror(errno));
+ return -errno;
+ }
+
+ ret = fstat(payload_fd, &s);
+ if (ret < 0) {
+ pr_err("Failed to stat payload \"%s\" (%s)\n",
+ filename, strerror(errno));
+ return -errno;
+ }
+
+ lseek(fd, *offset, SEEK_SET);
+
+ ret = mvebuimg_sendfile(fd, payload_fd, &csumm32.method, s.st_size);
+ if (ret < 0)
+ return ret;
+
+ /* pad to a multiple of 4 bytes */
+ ret = pwrite(fd, pad, ALIGN_SUP(s.st_size, 4) - s.st_size,
+ *offset + s.st_size);
+ if (ret < 0) {
+ pr_err("failed to write padding of payload\n");
+ return -errno;
+ }
+ *offset += ALIGN_SUP(s.st_size, 4);
+
+ /* For version 1 images the checksum doesn't seem to be necessary. We're
+ * still adding it for now to create bytewise identical images as
+ * kwbimage.
+ */
+ pad[0] = csumm32.csum;
+ pad[1] = csumm32.csum >> 8;
+ pad[2] = csumm32.csum >> 16;
+ pad[3] = csumm32.csum >> 24;
+
+ ret = pwrite(fd, pad, 4, *offset);
+ *offset += 4;
+
+ return 0;
+}
+
+/*
+ * Usage: create [-b binhdr]* [-o outputfilename] bootsrc payload
+ */
+static int mvebuimg_v1_create(int argc, char *const argv[])
+{
+ int opt;
+ char *output = NULL;
+ unsigned int extensionheaders = 0;
+ int fd, ret;
+ long l;
+ char *endptr;
+ char mainhdr[0x20] = { 0, };
+ struct mvebuimg_checksum_method8 csumm = {
+ .method = {
+ .update = mvebuimg_checksum8,
+ },
+ .csum = 0,
+ };
+ size_t offset, offset_payload;
+ size_t size_payload;
+ unsigned long payload_align = 4096;
+ int debug = 0;
+ long destaddr, execaddr;
+ int destaddr_provided = 0, execaddr_provided = 0;
+ uint8_t nand_blksz = 0;
+ uint8_t nand_bbloc = 0;
+
+ optind = 0;
+ while ((opt = getopt(argc, argv, "+a:b:B:Dd:e:o:")) != -1) {
+ switch (opt) {
+ case 'a':
+ errno = 0;
+ payload_align = strtol(optarg, &endptr, 0);
+ if (errno || *endptr != '\0' ||
+ !is_power_of_two(payload_align)) {
+ pr_err("Invalid payload alignment, must be a power of two\n");
+ return EXIT_FAILURE;
+ }
+ break;
+
+ case 'b':
+ ++extensionheaders;
+ break;
+
+ case 'B':
+ errno = 0;
+ l = strtol(optarg, &endptr, 0);
+ if (errno || (*endptr != '\0' && *endptr != ':') ||
+ (l != 0 && (l < 0x10000 || l > 0xff0000 ||
+ !is_power_of_two(l)))) {
+ pr_err("Invalid NAND block size\n");
+ return EXIT_FAILURE;
+ }
+ nand_blksz = l >> 16;
+
+ if (*endptr != ':')
+ break;
+
+ if ((*(endptr + 1) == '0' || *(endptr + 1) == '1') &&
+ *(endptr + 2) == '\0') {
+ nand_bbloc = *(endptr + 1) - '0';
+ } else {
+ pr_err("Invalid NAND bad block location\n");
+ return EXIT_FAILURE;
+ }
+
+ break;
+
+ case 'D':
+ debug = 1;
+ break;
+
+ case 'd':
+ errno = 0;
+ destaddr = strtol(optarg, &endptr, 0);
+ if (errno || *endptr != '\0' ||
+ destaddr < 0 || destaddr > 0xffffffff) {
+ pr_err("invalid dest address\n");
+ return EXIT_FAILURE;
+ }
+ destaddr_provided = 1;
+ break;
+
+ case 'e':
+ errno = 0;
+ execaddr = strtol(optarg, &endptr, 0);
+ if (errno || *endptr != '\0' ||
+ execaddr < 0 || execaddr > 0xffffffff) {
+ pr_err("invalid exec address\n");
+ return EXIT_FAILURE;
+ }
+ execaddr_provided = 1;
+ break;
+
+ case 'o':
+ if (output) {
+ pr_err("more than one output file specified\n");
+ return EXIT_FAILURE;
+ }
+ output = optarg;
+ break;
+
+ default:
+ pr_err("Unsupported option\n");
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (argc - optind < 2) {
+ pr_err("too few parameters\n");
+ return EXIT_FAILURE;
+ }
+
+ errno = 0;
+ l = strtol(argv[optind], &endptr, 0);
+ if (errno || *endptr != '\0' || l < 0 || l > 0xff) {
+ int i;
+ int idfound = 0;
+
+ for (i = 0; boot_ids[i].name; ++i) {
+ if (strcmp(boot_ids[i].name, argv[optind]) == 0) {
+ mainhdr[0] = boot_ids[i].id;
+ idfound = 1;
+ break;
+ }
+ }
+
+ if (!idfound) {
+ fprintf(stderr, "failed to parse bootsrc\n");
+ return EXIT_FAILURE;
+ }
+
+ } else {
+ mainhdr[0] = l;
+ }
+
+ if (!destaddr_provided)
+ destaddr = 0x1000000;
+
+ if (!execaddr_provided)
+ execaddr = destaddr;
+
+ if (!output) {
+ pr_err("no output option given\n");
+ return EXIT_FAILURE;
+ }
+
+ fd = open(output, O_CREAT | O_WRONLY | O_TRUNC, 0644);
+ if (fd < 0) {
+ pr_err("failed to open output\n");
+ return EXIT_FAILURE;
+ }
+
+ if (extensionheaders)
+ mainhdr[0x1e] = 1;
+
+ offset = 0x20;
+ optind = 0;
+ while ((opt = getopt(argc, argv, "+a:b:B:Dd:e:o:")) != -1) {
+ switch (opt) {
+ case 'b':
+ --extensionheaders;
+
+ ret = mvebuimg_v1_write_binhdr(fd, &offset, optarg,
+ &csumm,
+ extensionheaders == 0);
+ if (ret < 0)
+ return EXIT_FAILURE;
+
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* Align the payload to a reasonable boundary */
+ offset = offset_payload = ALIGN_SUP(offset, 4096);
+
+ /* BootROM debugging */
+ mainhdr[0x01] = debug ? 0x1 : 0x0;
+
+ /* Boot Image Format Version */
+ mainhdr[0x08] = 0x1;
+
+ /* Header size */
+ mainhdr[0x09] = offset_payload >> 16;
+ mainhdr[0x0a] = offset_payload;
+ mainhdr[0x0b] = offset_payload >> 8;
+
+ /* Offset of payload in the image */
+ mainhdr[0x0c] = (char)offset_payload;
+ mainhdr[0x0d] = (char)(offset_payload >> 8);
+ mainhdr[0x0e] = (char)(offset_payload >> 16);
+ mainhdr[0x0f] = (char)(offset_payload >> 24);
+
+ /* Address to load the image to */
+ mainhdr[0x10] = (char)destaddr;
+ mainhdr[0x11] = (char)(destaddr >> 8);
+ mainhdr[0x12] = (char)(destaddr >> 16);
+ mainhdr[0x13] = (char)(destaddr >> 24);
+
+ /* Entry point */
+ mainhdr[0x14] = (char)execaddr;
+ mainhdr[0x15] = (char)(execaddr >> 8);
+ mainhdr[0x16] = (char)(execaddr >> 16);
+ mainhdr[0x17] = (char)(execaddr >> 24);
+
+ /* For NAND images set block size and bad block location */
+ mainhdr[0x19] = nand_blksz;
+ mainhdr[0x1a] = nand_bbloc;
+
+ ret = mvebuimg_v1_write_payload(fd, &offset, argv[optind + 1]);
+ if (ret < 0)
+ return EXIT_FAILURE;
+
+ size_payload = offset - offset_payload;
+ mainhdr[0x04] = (char)size_payload;
+ mainhdr[0x05] = (char)(size_payload >> 8);
+ mainhdr[0x06] = (char)(size_payload >> 16);
+ mainhdr[0x07] = (char)(size_payload >> 24);
+
+ csumm.method.update(&csumm.method, mainhdr, sizeof(mainhdr));
+ mainhdr[0x1f] = csumm.csum;
+ ret = pwrite(fd, mainhdr, sizeof(mainhdr), 0);
+ if (ret < 0) {
+ pr_err("failure write main header (%s)\n",
+ strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ ret = close(fd);
+ if (ret) {
+ pr_err("failure during output closing (%s)\n",
+ strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
+
+static const struct {
+ const char *name;
+ int (*func[2])(int argc, char *const argv[]);
+} commands[] = {
+ {
+ .name = "create",
+ .func = { NULL, mvebuimg_v1_create }
+ }, {
+ /* sentinel */
+ }
+};
+
+int main(int argc, char *const argv[])
+{
+ int opt;
+ long version = -1;
+ int i;
+
+ char *endptr;
+
+ optind = 0;
+ while ((opt = getopt(argc, argv, "+v:")) != -1) {
+ switch (opt) {
+ case 'v':
+ errno = 0;
+ version = strtol(optarg, &endptr, 0);
+ if (errno || *endptr != '\0' ||
+ version < 0 || version > 1) {
+ pr_err("Unsupported version\n");
+ return EXIT_FAILURE;
+ }
+ break;
+ default:
+ pr_err("Unsupported option\n");
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (version < 0) {
+ pr_info("Defaulting to version 1\n");
+ version = 1;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1) {
+ pr_err("No command given\n");
+ return EXIT_FAILURE;
+ }
+
+ for (i = 0; commands[i].name != NULL; ++i) {
+ if (strcmp(commands[i].name, argv[0]) == 0) {
+ if (!commands[i].func[version]) {
+ pr_err("ERROR: command not implemented\n");
+ return EXIT_FAILURE;
+ }
+ return commands[i].func[version](argc, argv);
+ }
+ }
+
+ pr_err("command \"%s\" not found\n", argv[0]);
+ return EXIT_FAILURE;
+}