diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2019-07-12 07:10:18 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-07-12 07:10:18 +0200 |
commit | ca1c1456a16ee50f60f53e4efda04b310372a9b7 (patch) | |
tree | 02a289570992a3acb951841709741cdb4bbf0ade | |
parent | 5ed435f33dc6a31cd93b6f38a14dd775977cf1cc (diff) | |
parent | 8a16615f9efe7e0f94c6c8132c0df4e3ad0d7f44 (diff) | |
download | barebox-ca1c1456a16ee50f60f53e4efda04b310372a9b7.tar.gz barebox-ca1c1456a16ee50f60f53e4efda04b310372a9b7.tar.xz |
Merge branch 'for-next/mvebu'
-rw-r--r-- | arch/arm/boards/globalscale-mirabox/kwbimage.cfg | 5 | ||||
-rw-r--r-- | arch/arm/boards/lenovo-ix4-300d/kwbimage.cfg | 5 | ||||
-rw-r--r-- | arch/arm/boards/marvell-armada-xp-db/kwbimage.cfg | 3 | ||||
-rw-r--r-- | arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg | 3 | ||||
-rw-r--r-- | arch/arm/boards/netgear-rn104/kwbimage.cfg | 7 | ||||
-rw-r--r-- | arch/arm/boards/netgear-rn2120/kwbimage.cfg | 7 | ||||
-rw-r--r-- | arch/arm/boards/plathome-openblocks-ax3/kwbimage.cfg | 3 | ||||
-rw-r--r-- | arch/arm/boards/turris-omnia/kwbimage.cfg | 7 | ||||
-rw-r--r-- | images/Makefile.mvebu | 93 | ||||
-rw-r--r-- | scripts/Makefile | 2 | ||||
-rw-r--r-- | scripts/Makefile.lib | 3 | ||||
-rw-r--r-- | scripts/mvebuimg.c | 569 |
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; +} |