diff mbox

[LEDE-DEV] ar71xx: add support for Buffalo BHR-4GRV2

Message ID 20161108134500.23867-1-naobsd@gmail.com
State Accepted
Headers show

Commit Message

FUKAUMI Naoki Nov. 8, 2016, 1:45 p.m. UTC
Signed-off-by: FUKAUMI Naoki <naobsd@gmail.com>
---
 target/linux/ar71xx/base-files/etc/board.d/01_leds |   4 +
 .../linux/ar71xx/base-files/etc/board.d/02_network |   1 +
 target/linux/ar71xx/base-files/etc/diag.sh         |   9 +-
 target/linux/ar71xx/base-files/lib/ar71xx.sh       |   3 +
 .../lib/preinit/05_set_preinit_iface_ar71xx        |   1 +
 .../ar71xx/base-files/lib/upgrade/platform.sh      |   1 +
 target/linux/ar71xx/config-4.4                     |   1 +
 .../ar71xx/files/arch/mips/ath79/Kconfig.openwrt   |   8 +
 target/linux/ar71xx/files/arch/mips/ath79/Makefile |   1 +
 .../ar71xx/files/arch/mips/ath79/mach-bhr-4grv2.c  | 171 ++++++++++++++++
 .../linux/ar71xx/files/arch/mips/ath79/machtypes.h |   1 +
 target/linux/ar71xx/image/generic.mk               |  21 ++
 tools/firmware-utils/Makefile                      |   1 +
 tools/firmware-utils/src/mkbuffaloimg.c            | 223 +++++++++++++++++++++
 14 files changed, 442 insertions(+), 4 deletions(-)
 create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-bhr-4grv2.c
 create mode 100644 tools/firmware-utils/src/mkbuffaloimg.c
diff mbox

Patch

diff --git a/target/linux/ar71xx/base-files/etc/board.d/01_leds b/target/linux/ar71xx/base-files/etc/board.d/01_leds
index cde3a94..64301b2 100755
--- a/target/linux/ar71xx/base-files/etc/board.d/01_leds
+++ b/target/linux/ar71xx/base-files/etc/board.d/01_leds
@@ -57,6 +57,10 @@  ap147-010)
 	ucidef_set_led_switch "lan4" "LAN4" "ap147:green:lan4" "switch0" "0x02"
 	ucidef_set_led_wlan "wlan2g" "WLAN 2.4 GHz" "ap147:green:wlan-2g" "phy0tpt"
 	;;
+bhr-4grv2)
+	ucidef_set_led_default "power" "POWER" "buffalo:green:power" "1"
+	ucidef_set_led_default "diag" "DIAG" "buffalo:red:diag" "0"
+	;;
 bsb)
 	ucidef_set_led_default "sys" "SYS" "$board:red:sys" "1"
 	;;
diff --git a/target/linux/ar71xx/base-files/etc/board.d/02_network b/target/linux/ar71xx/base-files/etc/board.d/02_network
index 24dfced..df87c96 100755
--- a/target/linux/ar71xx/base-files/etc/board.d/02_network
+++ b/target/linux/ar71xx/base-files/etc/board.d/02_network
@@ -164,6 +164,7 @@  ar71xx_setup_interfaces()
 		;;
 	ap135-020|\
 	ap136-020|\
+	bhr-4grv2|\
 	tew-823dru|\
 	tl-wr1043nd-v2|\
 	wzr-450hp2)
diff --git a/target/linux/ar71xx/base-files/etc/diag.sh b/target/linux/ar71xx/base-files/etc/diag.sh
index 881b3c6..bfd619a 100644
--- a/target/linux/ar71xx/base-files/etc/diag.sh
+++ b/target/linux/ar71xx/base-files/etc/diag.sh
@@ -53,6 +53,11 @@  get_status_led() {
 	aw-nr580)
 		status_led="$board:green:ready"
 		;;
+	bhr-4grv2|\
+	wzr-hp-ag300h|\
+	wzr-hp-g300nh2)
+		status_led="buffalo:red:diag"
+		;;
 	bsb)
 		status_led="$board:red:sys"
 		;;
@@ -393,10 +398,6 @@  get_status_led() {
 	wlae-ag300n)
 		status_led="buffalo:green:status"
 		;;
-	wzr-hp-ag300h|\
-	wzr-hp-g300nh2)
-		status_led="buffalo:red:diag"
-		;;
 	r6100|\
 	wndap360|\
 	wndr3700|\
diff --git a/target/linux/ar71xx/base-files/lib/ar71xx.sh b/target/linux/ar71xx/base-files/lib/ar71xx.sh
index 7554247..9495bf4 100755
--- a/target/linux/ar71xx/base-files/lib/ar71xx.sh
+++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh
@@ -482,6 +482,9 @@  ar71xx_board_detect() {
 	*AW-NR580)
 		name="aw-nr580"
 		;;
+	*BHR-4GRV2)
+		name="bhr-4grv2"
+		;;
 	*CAP324)
 		name="cap324"
 		;;
diff --git a/target/linux/ar71xx/base-files/lib/preinit/05_set_preinit_iface_ar71xx b/target/linux/ar71xx/base-files/lib/preinit/05_set_preinit_iface_ar71xx
index c4177e1..e2a70b8 100644
--- a/target/linux/ar71xx/base-files/lib/preinit/05_set_preinit_iface_ar71xx
+++ b/target/linux/ar71xx/base-files/lib/preinit/05_set_preinit_iface_ar71xx
@@ -16,6 +16,7 @@  set_preinit_iface() {
 	ap83 |\
 	archer-c5 |\
 	archer-c7 |\
+	bhr-4grv2 |\
 	dir-505-a1 |\
 	gl-inet |\
 	jwap003 |\
diff --git a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
index c4a9f8a..2358c58 100755
--- a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
@@ -263,6 +263,7 @@  platform_check_image() {
 	ap152|\
 	ap96|\
 	arduino-yun|\
+	bhr-4grv2|\
 	bxu2000n-2-a1|\
 	db120|\
 	dr344|\
diff --git a/target/linux/ar71xx/config-4.4 b/target/linux/ar71xx/config-4.4
index 4fe80f0..aa20f9b 100644
--- a/target/linux/ar71xx/config-4.4
+++ b/target/linux/ar71xx/config-4.4
@@ -53,6 +53,7 @@  CONFIG_ATH79_MACH_AP96=y
 CONFIG_ATH79_MACH_ARCHER_C7=y
 CONFIG_ATH79_MACH_ARDUINO_YUN=y
 CONFIG_ATH79_MACH_AW_NR580=y
+CONFIG_ATH79_MACH_BHR_4GRV2=y
 CONFIG_ATH79_MACH_BHU_BXU2000N2_A=y
 CONFIG_ATH79_MACH_BSB=y
 CONFIG_ATH79_MACH_C55=y
diff --git a/target/linux/ar71xx/files/arch/mips/ath79/Kconfig.openwrt b/target/linux/ar71xx/files/arch/mips/ath79/Kconfig.openwrt
index db3b9bd..ac8255b 100644
--- a/target/linux/ar71xx/files/arch/mips/ath79/Kconfig.openwrt
+++ b/target/linux/ar71xx/files/arch/mips/ath79/Kconfig.openwrt
@@ -271,6 +271,14 @@  config ATH79_MACH_SOM9331
 	select ATH79_DEV_USB
 	select ATH79_DEV_WMAC
 
+config ATH79_MACH_BHR_4GRV2
+	bool "Buffalo BHR-4GRV2 board support"
+	select SOC_QCA955X
+	select ATH79_DEV_ETH
+	select ATH79_DEV_GPIO_BUTTONS
+	select ATH79_DEV_LEDS_GPIO
+	select ATH79_DEV_M25P80
+
 config ATH79_MACH_WHR_HP_G300N
 	bool "Buffalo WHR-HP-G300N board support"
 	select SOC_AR724X
diff --git a/target/linux/ar71xx/files/arch/mips/ath79/Makefile b/target/linux/ar71xx/files/arch/mips/ath79/Makefile
index 580d2e2..78e242a 100644
--- a/target/linux/ar71xx/files/arch/mips/ath79/Makefile
+++ b/target/linux/ar71xx/files/arch/mips/ath79/Makefile
@@ -59,6 +59,7 @@  obj-$(CONFIG_ATH79_MACH_AP96)			+= mach-ap96.o
 obj-$(CONFIG_ATH79_MACH_ARCHER_C7)		+= mach-archer-c7.o
 obj-$(CONFIG_ATH79_MACH_ARDUINO_YUN)		+= mach-arduino-yun.o
 obj-$(CONFIG_ATH79_MACH_AW_NR580)		+= mach-aw-nr580.o
+obj-$(CONFIG_ATH79_MACH_BHR_4GRV2)		+= mach-bhr-4grv2.o
 obj-$(CONFIG_ATH79_MACH_BHU_BXU2000N2_A)	+= mach-bhu-bxu2000n2-a.o
 obj-$(CONFIG_ATH79_MACH_BSB)			+= mach-bsb.o
 obj-$(CONFIG_ATH79_MACH_C55)			+= mach-c55.o
diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-bhr-4grv2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-bhr-4grv2.c
new file mode 100644
index 0000000..5b4cf5f
--- /dev/null
+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-bhr-4grv2.c
@@ -0,0 +1,171 @@ 
+/*
+ * Buffalo BHR-4GRV2 board support
+ *
+ * Copyright (c) 2012 Qualcomm Atheros
+ * Copyright (c) 2012-2013 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (c) 2016 FUKAUMI Naoki <naobsd@gmail.com>
+ *
+ * Based on mach-ap136.c and mach-wzr-450hp2.c
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/ar8216_platform.h>
+
+#include <asm/mach-ath79/ar71xx_regs.h>
+
+#include "common.h"
+#include "dev-eth.h"
+#include "dev-gpio-buttons.h"
+#include "dev-leds-gpio.h"
+#include "dev-m25p80.h"
+#include "machtypes.h"
+
+#define BHR_4GRV2_GPIO_LED_VPN_RED	3
+#define BHR_4GRV2_GPIO_LED_VPN_GREEN	18
+#define BHR_4GRV2_GPIO_LED_POWER_GREEN	19
+#define BHR_4GRV2_GPIO_LED_DIAG_RED	20
+
+#define BHR_4GRV2_GPIO_BTN_RESET	17
+#define BHR_4GRV2_GPIO_BTN_ECO		21
+
+#define BHR_4GRV2_KEYS_POLL_INTERVAL	20	/* msecs */
+#define BHR_4GRV2_KEYS_DEBOUNCE_INTERVAL	(3 * BHR_4GRV2_KEYS_POLL_INTERVAL)
+#define BHR_4GRV2_MAC0_OFFSET		0
+#define BHR_4GRV2_MAC1_OFFSET		6
+
+static struct gpio_led bhr_4grv2_leds_gpio[] __initdata = {
+	{
+		.name		= "buffalo:red:vpn",
+		.gpio		= BHR_4GRV2_GPIO_LED_VPN_RED,
+		.active_low	= 1,
+	},
+	{
+		.name		= "buffalo:green:vpn",
+		.gpio		= BHR_4GRV2_GPIO_LED_VPN_GREEN,
+		.active_low	= 1,
+	},
+	{
+		.name		= "buffalo:green:power",
+		.gpio		= BHR_4GRV2_GPIO_LED_POWER_GREEN,
+		.active_low	= 1,
+	},
+	{
+		.name		= "buffalo:red:diag",
+		.gpio		= BHR_4GRV2_GPIO_LED_DIAG_RED,
+		.active_low	= 1,
+	}
+};
+
+static struct gpio_keys_button bhr_4grv2_gpio_keys[] __initdata = {
+	{
+		.desc		= "Reset button",
+		.type		= EV_KEY,
+		.code		= KEY_RESTART,
+		.debounce_interval = BHR_4GRV2_KEYS_DEBOUNCE_INTERVAL,
+		.gpio		= BHR_4GRV2_GPIO_BTN_RESET,
+		.active_low	= 1,
+	},
+	{
+		.desc		= "ECO button",
+		.type		= EV_KEY,
+		.code		= BTN_0,
+		.debounce_interval = BHR_4GRV2_KEYS_DEBOUNCE_INTERVAL,
+		.gpio		= BHR_4GRV2_GPIO_BTN_ECO,
+		.active_low	= 1,
+	},
+};
+
+/* GMAC0 of the AR8327 switch is connected to GMAC1 via SGMII */
+static struct ar8327_pad_cfg bhr_4grv2_ar8327_pad0_cfg = {
+	.mode = AR8327_PAD_MAC_SGMII,
+	.sgmii_delay_en = true,
+};
+
+/* GMAC6 of the AR8327 switch is connected to GMAC0 via RGMII */
+static struct ar8327_pad_cfg bhr_4grv2_ar8327_pad6_cfg = {
+	.mode = AR8327_PAD_MAC_RGMII,
+	.txclk_delay_en = true,
+	.rxclk_delay_en = true,
+	.txclk_delay_sel = AR8327_CLK_DELAY_SEL1,
+	.rxclk_delay_sel = AR8327_CLK_DELAY_SEL2,
+};
+
+static struct ar8327_platform_data bhr_4grv2_ar8327_data = {
+	.pad0_cfg = &bhr_4grv2_ar8327_pad0_cfg,
+	.pad6_cfg = &bhr_4grv2_ar8327_pad6_cfg,
+	.port0_cfg = {
+		.force_link = 1,
+		.speed = AR8327_PORT_SPEED_1000,
+		.duplex = 1,
+		.txpause = 1,
+		.rxpause = 1,
+	},
+	.port6_cfg = {
+		.force_link = 1,
+		.speed = AR8327_PORT_SPEED_1000,
+		.duplex = 1,
+		.txpause = 1,
+		.rxpause = 1,
+	},
+};
+
+static struct mdio_board_info bhr_4grv2_mdio0_info[] = {
+	{
+		.bus_id = "ag71xx-mdio.0",
+		.phy_addr = 0,
+		.platform_data = &bhr_4grv2_ar8327_data,
+	},
+};
+
+static void __init bhr_4grv2_setup(void)
+{
+	u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
+
+	ath79_register_m25p80(NULL);
+
+	ath79_register_leds_gpio(-1, ARRAY_SIZE(bhr_4grv2_leds_gpio),
+				 bhr_4grv2_leds_gpio);
+	ath79_register_gpio_keys_polled(-1, BHR_4GRV2_KEYS_POLL_INTERVAL,
+					ARRAY_SIZE(bhr_4grv2_gpio_keys),
+					bhr_4grv2_gpio_keys);
+
+	mdiobus_register_board_info(bhr_4grv2_mdio0_info,
+				    ARRAY_SIZE(bhr_4grv2_mdio0_info));
+	ath79_register_mdio(0, 0x0);
+
+	ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN);
+
+	/* GMAC0 is connected to the RGMII interface */
+	ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
+	ath79_eth0_data.phy_mask = BIT(0);
+	ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev;
+	ath79_eth0_pll_data.pll_1000 = 0x56000000;
+
+	ath79_init_mac(ath79_eth0_data.mac_addr, art + BHR_4GRV2_MAC0_OFFSET, 0);
+	ath79_register_eth(0);
+
+	/* GMAC1 is connected to the SGMII interface */
+	ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII;
+	ath79_eth1_data.speed = SPEED_1000;
+	ath79_eth1_data.duplex = DUPLEX_FULL;
+	ath79_eth1_pll_data.pll_1000 = 0x03000101;
+
+	ath79_init_mac(ath79_eth1_data.mac_addr, art + BHR_4GRV2_MAC1_OFFSET, 0);
+	ath79_register_eth(1);
+}
+
+MIPS_MACHINE(ATH79_MACH_BHR_4GRV2, "BHR-4GRV2",
+	     "Buffalo BHR-4GRV2", bhr_4grv2_setup);
diff --git a/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h b/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h
index 3ebcbc0..dec3d60 100644
--- a/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h
+++ b/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h
@@ -44,6 +44,7 @@  enum ath79_mach_type {
 	ATH79_MACH_ARCHER_C7_V2,		/* TP-LINK Archer C7 V2 board */
 	ATH79_MACH_ARDUINO_YUN,			/* Yun */
 	ATH79_MACH_AW_NR580,			/* AzureWave AW-NR580 */
+	ATH79_MACH_BHR_4GRV2,			/* Buffalo BHR-4GRV2 */
 	ATH79_MACH_BHU_BXU2000N2_A1,		/* BHU BXU2000n-2 A1 */
 	ATH79_MACH_BSB,				/* Smart Electronics Black Swift board */
 	ATH79_MACH_C55,				/* AirTight Networks C-55 */
diff --git a/target/linux/ar71xx/image/generic.mk b/target/linux/ar71xx/image/generic.mk
index ae0c7fc..d6142c1 100644
--- a/target/linux/ar71xx/image/generic.mk
+++ b/target/linux/ar71xx/image/generic.mk
@@ -626,3 +626,24 @@  define Device/dap-2695-a1
 endef
 
 TARGET_DEVICES += dap-2695-a1
+
+define Build/mkbuffaloimg
+	$(STAGING_DIR_HOST)/bin/mkbuffaloimg -B $(BOARDNAME) \
+		-R $$(($(subst k, * 1024,$(ROOTFS_SIZE)))) \
+		-K $$(($(subst k, * 1024,$(KERNEL_SIZE)))) \
+		-i $@ -o $@.new
+	mv $@.new $@
+endef
+
+define Device/bhr-4grv2
+  DEVICE_TITLE := Buffalo BHR-4GRV2
+  BOARDNAME := BHR-4GRV2
+  ROOTFS_SIZE := 14528k
+  KERNEL_SIZE := 1472k
+  IMAGE_SIZE := 16000k
+  MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,14528k(rootfs),1472k(kernel),64k(art)ro,16000k@0x50000(firmware)
+  IMAGES := sysupgrade.bin factory.bin
+  IMAGE/sysupgrade.bin = append-rootfs | pad-rootfs | pad-to $$$$(ROOTFS_SIZE) | append-kernel | check-size $$$$(IMAGE_SIZE)
+  IMAGE/factory.bin = append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | mkbuffaloimg
+endef
+TARGET_DEVICES += bhr-4grv2
diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile
index 320d1db..1cfc885 100644
--- a/tools/firmware-utils/Makefile
+++ b/tools/firmware-utils/Makefile
@@ -77,6 +77,7 @@  define Host/Compile
 	$(call cc,mkmerakifw sha1, -Wall)
 	$(call cc,mkmerakifw-old, -Wall)
 	$(call cc,jcgimage, -lz -Wall)
+	$(call cc,mkbuffaloimg, -Wall)
 endef
 
 define Host/Install
diff --git a/tools/firmware-utils/src/mkbuffaloimg.c b/tools/firmware-utils/src/mkbuffaloimg.c
new file mode 100644
index 0000000..364dda0
--- /dev/null
+++ b/tools/firmware-utils/src/mkbuffaloimg.c
@@ -0,0 +1,223 @@ 
+/*
+ *  Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2016 FUKAUMI Naoki <naobsd@gmail.com>
+ *
+ *  Based on mkdniimg.c
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>     /* for unlink() */
+#include <libgen.h>
+#include <getopt.h>     /* for getopt() */
+#include <stdarg.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#define DNI_HDR_LEN	128
+
+/*
+ * Globals
+ */
+static char *ifname;
+static char *progname;
+static char *ofname;
+static char *version = "0.00_0.00";
+static char *region = "JP";
+static char *rootfs_size;
+static char *kernel_size;
+
+static char *board_id;
+/*
+ * Message macros
+ */
+#define ERR(fmt, ...) do { \
+	fflush(0); \
+	fprintf(stderr, "[%s] *** error: " fmt "\n", \
+			progname, ## __VA_ARGS__ ); \
+} while (0)
+
+#define ERRS(fmt, ...) do { \
+	int save = errno; \
+	fflush(0); \
+	fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \
+			progname, ## __VA_ARGS__, strerror(save)); \
+} while (0)
+
+void usage(int status)
+{
+	FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
+
+	fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);
+	fprintf(stream,
+"\n"
+"Options:\n"
+"  -B <board>       create image for the board specified with <board>\n"
+"  -i <file>        read input from the file <file>\n"
+"  -o <file>        write output to the file <file>\n"
+"  -v <version>     set image version to <version>\n"
+"  -r <region>      set image region to <region>\n"
+"  -R <rootfs_size> set RootfsSize to <rootfs_size>\n"
+"  -K <kernel_size> set KernelSize to <kernel_size>\n"
+"  -h               show this screen\n"
+	);
+
+	exit(status);
+}
+
+int main(int argc, char *argv[])
+{
+	int res = EXIT_FAILURE;
+	int buflen;
+	int err;
+	struct stat st;
+	char *buf;
+	int i;
+	uint8_t csum;
+
+	FILE *outfile, *infile;
+
+	progname = basename(argv[0]);
+
+	while ( 1 ) {
+		int c;
+
+		c = getopt(argc, argv, "B:i:o:v:r:R:K:h");
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'B':
+			board_id = optarg;
+			break;
+		case 'i':
+			ifname = optarg;
+			break;
+		case 'o':
+			ofname = optarg;
+			break;
+		case 'v':
+			version = optarg;
+			break;
+		case 'r':
+			region = optarg;
+			break;
+		case 'R':
+			rootfs_size = optarg;
+			break;
+		case 'K':
+			kernel_size = optarg;
+			break;
+		case 'h':
+			usage(EXIT_SUCCESS);
+			break;
+		default:
+			usage(EXIT_FAILURE);
+			break;
+		}
+	}
+
+	if (board_id == NULL) {
+		ERR("no board specified");
+		goto err;
+	}
+
+	if (rootfs_size == NULL) {
+		ERR("no rootfs_size specified");
+		goto err;
+	}
+
+	if (kernel_size == NULL) {
+		ERR("no kernel_size specified");
+		goto err;
+	}
+
+	if (ifname == NULL) {
+		ERR("no input file specified");
+		goto err;
+	}
+
+	if (ofname == NULL) {
+		ERR("no output file specified");
+		goto err;
+	}
+
+	err = stat(ifname, &st);
+	if (err){
+		ERRS("stat failed on %s", ifname);
+		goto err;
+	}
+
+	buflen = st.st_size + DNI_HDR_LEN + 1;
+	buf = malloc(buflen);
+	if (!buf) {
+		ERR("no memory for buffer\n");
+		goto err;
+	}
+
+	memset(buf, 0, DNI_HDR_LEN);
+	snprintf(buf, DNI_HDR_LEN, "device:%s\nversion:%s\nregion:%s\n"
+		 "RootfsSize:%s\nKernelSize:%s\nInfoHeadSize:128\n",
+		 board_id, version, region, rootfs_size, kernel_size);
+	buf[DNI_HDR_LEN - 2] = 0x12;
+	buf[DNI_HDR_LEN - 1] = 0x32;
+
+	infile = fopen(ifname, "r");
+	if (infile == NULL) {
+		ERRS("could not open \"%s\" for reading", ifname);
+		goto err_free;
+	}
+
+	errno = 0;
+	fread(buf +  DNI_HDR_LEN, st.st_size, 1, infile);
+	if (errno != 0) {
+		ERRS("unable to read from file %s", ifname);
+		goto err_close_in;
+	}
+
+	csum = 0;
+	for (i = 0; i < (st.st_size + DNI_HDR_LEN); i++)
+		csum += buf[i];
+
+	csum = 0xff - csum;
+	buf[st.st_size + DNI_HDR_LEN] = csum;
+
+	outfile = fopen(ofname, "w");
+	if (outfile == NULL) {
+		ERRS("could not open \"%s\" for writing", ofname);
+		goto err_close_in;
+	}
+
+	errno = 0;
+	fwrite(buf, buflen, 1, outfile);
+	if (errno) {
+		ERRS("unable to write to file %s", ofname);
+		goto err_close_out;
+	}
+
+	res = EXIT_SUCCESS;
+
+	fflush(outfile);
+
+ err_close_out:
+	fclose(outfile);
+	if (res != EXIT_SUCCESS) {
+		unlink(ofname);
+	}
+
+ err_close_in:
+	fclose(infile);
+
+ err_free:
+	free(buf);
+
+ err:
+	return res;
+}