Skip to content
Snippets Groups Projects
Commit a51ec563 authored by David Bauer's avatar David Bauer Committed by Andreas Ziegler
Browse files

ipq40xx: add support for ZyXEL NBG6617 (#1560)

parent d3f2c5f8
Branches
Tags
No related merge requests found
......@@ -315,6 +315,7 @@ ipq40xx
* ZyXEL
- NBG6617 [#80211s]_
- WRE6606 [#80211s]_
ipq806x
......
From: Christian Lamparter <chunkeey@googlemail.com>
Date: Thu, 21 Jun 2018 14:24:59 +0200
Subject: ipq40xx: add support for the ZyXEL NBG6617
This patch adds support for ZyXEL NBG6617
Hardware highlights:
SOC: IPQ4018 / QCA Dakota
CPU: Quad-Core ARMv7 Processor rev 5 (v7l) Cortex-A7
DRAM: 256 MiB DDR3L-1600/1866 Nanya NT5CC128M16IP-DI @ 537 MHz
NOR: 32 MiB Macronix MX25L25635F
ETH: Qualcomm Atheros QCA8075 Gigabit Switch (4 x LAN, 1 x WAN)
USB: 1 x 3.0 (via Synopsys DesignWare DWC3 controller in the SoC)
WLAN1: Qualcomm Atheros QCA4018 2.4GHz 802.11bgn 2:2x2
WLAN2: Qualcomm Atheros QCA4018 5GHz 802.11a/n/ac 2:2x2
INPUT: RESET Button, WIFI/Rfkill Togglebutton, WPS Button
LEDS: Power, WAN, LAN 1-4, WLAN 2.4GHz, WLAN 5GHz, USB, WPS
Serial:
WARNING: The serial port needs a TTL/RS-232 3.3v level converter!
The Serial setting is 115200-8-N-1. The 1x4 .1" header comes
pre-soldered. Pinout:
1. 3v3 (Label printed on the PCB), 2. RX, 3. GND, 4. TX
first install / debricking / restore stock:
0. Have a PC running a tftp-server @ 192.168.1.99/24
1. connect the PC to any LAN-Ports
2. put the openwrt...-factory.bin (or V1.00(ABCT.X).bin for stock) file
into the tftp-server root directory and rename it to just "ras.bin".
3. power-cycle the router and hold down the the WPS button (for 30sek)
4. Wait (for a long time - the serial console provides some progress
reports. The u-boot says it best: "Please be patient".
5. Once the power LED starts to flashes slowly and the USB + WPS LEDs
flashes fast at the same time. You have to reboot the device and
it should then come right up.
Installation via Web-UI:
0. Connect a PC to the powered-on router. It will assign your PC a
IP-address via DHCP
1. Access the Web-UI at 192.168.1.1 (Default Passwort: 1234)
2. Go to the "Expert Mode"
3. Under "Maintenance", select "Firmware-Upgrade"
4. Upload the OpenWRT factory image
5. Wait for the Device to finish.
It will reboot into OpenWRT without any additional actions needed.
To open the ZyXEL NBG6617:
0. remove the four rubber feet glued on the backside
1. remove the four philips screws and pry open the top cover
(by applying force between the plastic top housing from the
backside/lan-port side)
Access the real u-boot shell:
ZyXEL uses a proprietary loader/shell on top of u-boot: "ZyXEL zloader v2.02"
When the device is starting up, the user can enter the the loader shell
by simply pressing a key within the 3 seconds once the following string
appears on the serial console:
| Hit any key to stop autoboot: 3
The user is then dropped to a locked shell.
|NBG6617> HELP
|ATEN x[,y] set BootExtension Debug Flag (y=password)
|ATSE x show the seed of password generator
|ATSH dump manufacturer related data in ROM
|ATRT [x,y,z,u] RAM read/write test (x=level, y=start addr, z=end addr, u=iterations)
|ATGO boot up whole system
|ATUR x upgrade RAS image (filename)
|NBG6617>
In order to escape/unlock a password challenge has to be passed.
Note: the value is dynamic! you have to calculate your own!
First use ATSE $MODELNAME (MODELNAME is the hostname in u-boot env)
to get the challange value/seed.
|NBG6617> ATSE NBG6617
|012345678901
This seed/value can be converted to the password with the help of this
bash script (Thanks to http://www.adslayuda.com/Zyxel650-9.html authors):
- tool.sh -
ror32() {
echo $(( ($1 >> $2) | (($1 << (32 - $2) & (2**32-1)) ) ))
}
v="0x$1"
a="0x${v:2:6}"
b=$(( $a + 0x10F0A563))
c=$(( 0x${v:12:14} & 7 ))
p=$(( $(ror32 $b $c) ^ $a ))
printf "ATEN 1,%X\n" $p
- end of tool.sh -
|# bash ./tool.sh 012345678901
|
|ATEN 1,879C711
copy and paste the result into the shell to unlock zloader.
|NBG6617> ATEN 1,0046B0017430
If the entered code was correct the shell will change to
use the ATGU command to enter the real u-boot shell.
|NBG6617> ATGU
|NBG6617#
Co-authored-by: David Bauer <mail@david-bauer.net>
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
Signed-off-by: David Bauer <mail@david-bauer.net>
diff --git a/include/image-commands.mk b/include/image-commands.mk
index 4d3f025b123f44cfd48d5b6cf081ae7633577277..28b39c310e499caea4fe8a6d9ad6dceb5d95363b 100644
--- a/include/image-commands.mk
+++ b/include/image-commands.mk
@@ -49,6 +49,19 @@ define Build/eva-image
mv $@.new $@
endef
+define Build/make-ras
+ let \
+ newsize="$(subst k,* 1024,$(RAS_ROOTFS_SIZE))"; \
+ $(TOPDIR)/scripts/make-ras.sh \
+ --board $(RAS_BOARD) \
+ --version $(RAS_VERSION) \
+ --kernel $(call param_get_default,kernel,$(1),$(IMAGE_KERNEL)) \
+ --rootfs $@ \
+ --rootfssize $$newsize \
+ $@.new
+ @mv $@.new $@
+endef
+
define Build/netgear-chk
$(STAGING_DIR_HOST)/bin/mkchkimg \
-o $@.new \
diff --git a/package/boot/uboot-envtools/files/ipq40xx b/package/boot/uboot-envtools/files/ipq40xx
index d475e566299416176af3b8646a7510cd3c9787e7..8cd4799b295fd38c9e846af5769c9fa9f5490f8b 100644
--- a/package/boot/uboot-envtools/files/ipq40xx
+++ b/package/boot/uboot-envtools/files/ipq40xx
@@ -35,6 +35,9 @@ openmesh,a42 |\
openmesh,a62)
ubootenv_add_uci_config "/dev/mtd5" "0x0" "0x10000" "0x10000"
;;
+zyxel,nbg6617)
+ ubootenv_add_uci_config "/dev/mtd6" "0x0" "0x10000" "0x10000"
+ ;;
esac
config_load ubootenv
diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile
index 1cfcc33de3af58e9773d22cdcbe0c95f1633e2d9..b1428f173ddb507f0c92313dcca7aae57284a0b8 100644
--- a/package/firmware/ipq-wifi/Makefile
+++ b/package/firmware/ipq-wifi/Makefile
@@ -14,7 +14,7 @@ define Build/Compile
endef
#ALLWIFIBOARDS:=<devicename>
-ALLWIFIBOARDS:=zyxel_wre6606
+ALLWIFIBOARDS:=zyxel_nbg6617 zyxel_wre6606
ALLWIFIPACKAGES:=$(foreach BOARD,$(ALLWIFIBOARDS),ipq-wifi-$(BOARD))
define Package/ipq-wifi-default
@@ -50,5 +50,6 @@ endef
$(eval $(call generate-ipq-wifi-package,zyxel_wre6606,board-zyxel_wre6606.bin,ZyXEL WRE6606))
#$(eval $(call generate-ipq-wifi-package,<devicename>,<filename>,<displayname>))
+$(eval $(call generate-ipq-wifi-package,zyxel_nbg6617,board-zyxel_nbg6617.bin,ZyXEL NBG6617))
$(foreach PACKAGE,$(ALLWIFIPACKAGES),$(eval $(call BuildPackage,$(PACKAGE))))
diff --git a/package/firmware/ipq-wifi/board-zyxel_nbg6617.bin b/package/firmware/ipq-wifi/board-zyxel_nbg6617.bin
new file mode 100644
index 0000000000000000000000000000000000000000..ab4d43e8cbc949c06f74e332807b8d92239a7de0
GIT binary patch
literal 24276
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
literal 0
HcmV?d00001
diff --git a/scripts/make-ras.sh b/scripts/make-ras.sh
new file mode 100755
index 0000000000000000000000000000000000000000..ccddaa0016b0c926d4737abb5757e7212b0a1157
--- /dev/null
+++ b/scripts/make-ras.sh
@@ -0,0 +1,196 @@
+#!/usr/bin/env bash
+#
+# --- ZyXEL header format ---
+# Original Version by Benjamin Berg <benjamin@sipsolutions.net>
+#
+# The firmware image prefixed with a header (which is written into the MTD device).
+# The header is one erase block (~64KiB) in size, but the checksum only convers the
+# first 2KiB. Padding is 0xff. All integers are in big-endian.
+#
+# The checksum is always a 16-Bit System V checksum (sum -s) stored in a 32-Bit integer.
+#
+# 4 bytes: checksum of the rootfs image
+# 4 bytes: length of the contained rootfs image file (big endian)
+# 32 bytes: Firmware Version string (NUL terminated, 0xff padded)
+# 4 bytes: checksum over the header partition (big endian - see below)
+# 32 bytes: Model (e.g. "NBG6617", NUL termiated, 0xff padded)
+# 4 bytes: checksum of the kernel partition
+# 4 bytes: length of the contained kernel image file (big endian)
+# rest: 0xff padding
+#
+# The checksums are calculated by adding up all bytes and if a 16bit
+# overflow occurs, one is added and the sum is masked to 16 bit:
+# csum = csum + databyte; if (csum > 0xffff) { csum += 1; csum &= 0xffff };
+# Should the file have an odd number of bytes then the byte len-0x800 is
+# used additionally.
+#
+# The checksum for the header is calculated over the first 2048 bytes with
+# the rootfs image checksum as the placeholder during calculation.
+#
+# The header is padded with 0xff to the erase block size of the device.
+#
+board=""
+version=""
+kernel=""
+rootfs=""
+outfile=""
+err=""
+
+while [ "$1" ]; do
+ case "$1" in
+ "--board")
+ board="$2"
+ shift
+ shift
+ continue
+ ;;
+ "--version")
+ version="$2"
+ shift
+ shift
+ continue
+ ;;
+ "--kernel")
+ kernel="$2"
+ shift
+ shift
+ continue
+ ;;
+ "--rootfs")
+ rootfs="$2"
+ shift
+ shift
+ continue
+ ;;
+ "--rootfssize")
+ rootfssize="$2"
+ shift
+ shift
+ continue
+ ;;
+ *)
+ if [ ! "$outfile" ]; then
+ outfile=$1
+ shift
+ continue
+ fi
+ ;;
+ esac
+done
+
+if [ ! -n "$board" -o ! -n "$version" -o ! -r "$kernel" -o ! -r "$rootfs" -o ! "$rootfssize" -o ! "$outfile" ]; then
+ echo "syntax: $0 [--board ras-boardname] [--version ras-version] [--kernel kernelimage] [--rootfs rootfs] out"
+ exit 1
+fi
+
+rootfs_len=$(wc -c < "$rootfs")
+
+if [ "$rootfs_len" -lt "$rootfssize" ]; then
+ dd if=$rootfs of=$rootfs.new bs=$rootfssize conv=sync
+ mv $rootfs.new $rootfs
+fi
+
+if [ ${#version} -ge 28 ]; then
+ echo "version: '$version' is too long"
+ exit 1
+fi
+
+tmpdir="$( mktemp -d 2> /dev/null )"
+if [ -z "$tmpdir" ]; then
+ # try OSX signature
+ tmpdir="$( mktemp -t 'ubitmp' -d )"
+fi
+
+if [ -z "$tmpdir" ]; then
+ exit 1
+fi
+
+to_be() {
+ local val="$1"
+ local size="$2"
+
+ case "$size" in
+ 4)
+ echo $(( "$val" >> 24 | ("$val" & 0xff0000) >> 8 | ("$val" & 0xff00) << 8 | ("$val" & 0xff) << 24 ))
+ ;;
+ 2)
+ echo $(( "$val" >> 8 | ("$val" & 0xff) << 8))
+ ;;
+ esac
+}
+
+checksum_file() {
+ local file=$1
+
+ # ZyXEL seems to use System V sum mode... Now this is classy, who would have thought?!
+ echo $(sum -s ${file} | cut -f1 -d" ")
+}
+
+append_bin() {
+ local val=$1
+ local size=$2
+ local file=$3
+
+ while [ "$size" -ne 0 ]; do
+ printf \\$(printf %o $(("$val" & 0xff))) >> "$file"
+ val=$(($val >> 8))
+ let size-=1
+ done
+ return
+}
+
+tf=${tmpdir}/out
+pad=$(printf '%0.1s' $(printf "\xff"){1..64})
+
+rootfs_header_file="$tmpdir/rootfs_header"
+rootfs_chksum=$(to_be $(checksum_file ${rootfs}) 4)
+rootfs_len=$(to_be $(wc -c < "$rootfs") 4)
+
+versionpadlen=$(( 32 - ( ${#version} + 1) ))
+
+# 4 bytes: checksum of the rootfs image
+append_bin "$rootfs_chksum" 4 "$rootfs_header_file"
+# 4 bytes: length of the contained rootfs image file (big endian)
+append_bin "$rootfs_len" 4 "$rootfs_header_file"
+# 32 bytes: Firmware Version string (NUL terminated, 0xff padded)
+printf "%s\x00%.*s" "$version" "$versionpadlen" "$pad" >> "$rootfs_header_file"
+
+kernel_header_file="$tmpdir/kernel_header"
+kernel_chksum=$(to_be $(checksum_file ${kernel}) 4)
+kernel_len=$(to_be $(wc -c < "$kernel") 4)
+
+# 4 bytes: checksum of the kernel image
+append_bin "$kernel_chksum" 4 "$kernel_header_file"
+# 4 bytes: length of the contained kernel image file (big endian)
+append_bin "$kernel_len" 4 "$kernel_header_file"
+
+board_header_file="$tmpdir/board_header"
+board_file="$tmpdir/board"
+boardpadlen=$(( 64 - ( ${#board} + 1) ))
+# 32 bytes: Model (e.g. "NBG6617", NUL termiated, 0xff padded)
+printf "%s\x00%.*s" "$board" "$boardpadlen" "$pad" > "$board_file"
+cat "$kernel_header_file" >> "$board_file"
+printf "%.12s" "$pad" >> "$board_file"
+# rest: 0xff padding
+for i in {1..511}; do
+ printf "%s%s" "$pad" "$pad" >> "$board_file"
+done
+
+tmp_board_file="$tmpdir/tmp_board_file"
+cat "$rootfs_header_file" > "$tmp_board_file"
+
+# The checksum for the header is calculated over the first 2048 bytes with
+# the rootfs image checksum as the placeholder during calculation.
+append_bin "$rootfs_chksum" 4 "$tmp_board_file"
+cat "$board_file" >> "$tmp_board_file"
+
+truncate -s 2048 $tmp_board_file
+board_chksum=$(to_be $(checksum_file ${tmp_board_file}) 4)
+
+# 4 bytes: checksum over the header partition (big endian)
+append_bin "$board_chksum" 4 "$board_header_file"
+cat "$board_file" >> "$board_header_file"
+
+cat "$rootfs_header_file" "$board_header_file" "$rootfs" "$kernel" > "$outfile"
+
+rm -rf "$tmpdir"
diff --git a/target/linux/ipq40xx/base-files/etc/board.d/01_leds b/target/linux/ipq40xx/base-files/etc/board.d/01_leds
index fcba2aea543cdead03ef372bc6b751481846fbf7..475a8623f705d683a7ee3521ee71f2b57fa2e44d 100755
--- a/target/linux/ipq40xx/base-files/etc/board.d/01_leds
+++ b/target/linux/ipq40xx/base-files/etc/board.d/01_leds
@@ -34,6 +34,11 @@ netgear,ex6150v2)
meraki,mr33)
ucidef_set_interface_lan "eth0"
;;
+zyxel,nbg6617)
+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "$board:green:wlan2G" "phy0tpt"
+ ucidef_set_led_wlan "wlan5g" "WLAN5G" "$board:green:wlan5G" "phy1tpt"
+ ucidef_set_led_usbport "usb" "USB" "${board}:green:usb" "usb1-port1" "usb2-port1" "usb3-port1" "usb4-port1"
+ ;;
zyxel,wre6606)
ucidef_set_led_wlan "wlan2g" "WLAN2G" "${boardname}:green:wlan2g" "phy0tpt"
ucidef_set_led_wlan "wlan5g" "WLAN5G" "${boardname}:green:wlan5g" "phy1tpt"
diff --git a/target/linux/ipq40xx/base-files/etc/board.d/02_network b/target/linux/ipq40xx/base-files/etc/board.d/02_network
index 03e0c0e16c33f43fafcbba9c5af4baf6dd73e425..5c90ef136fd7cbbe023001030d8c9003347bd249 100755
--- a/target/linux/ipq40xx/base-files/etc/board.d/02_network
+++ b/target/linux/ipq40xx/base-files/etc/board.d/02_network
@@ -48,6 +48,11 @@ netgear,ex6150v2 |\
zyxel,wre6606)
ucidef_set_interface_lan "eth0"
;;
+zyxel,nbg6617)
+ ucidef_set_interfaces_lan_wan "eth0" "eth1"
+ ucidef_add_switch "switch0" \
+ "0u@eth0" "1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1"
+ ;;
*)
echo "Unsupported hardware. Network interfaces not intialized"
;;
diff --git a/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
index d89ddf6e57ee9f759f6dcc7c7f8152c11305499b..1d4fd9cd8f9a3983ac3323ce72153c1dcc17a69a 100644
--- a/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
+++ b/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
@@ -146,6 +146,7 @@ case "$FIRMWARE" in
openmesh,a62)
ath10kcal_extract "0:ART" 4096 12064
;;
+ zyxel,nbg6617 |\
zyxel,wre6606)
ath10kcal_extract "ART" 4096 12064
ath10kcal_patch_mac_crc $(macaddr_add $(cat /sys/class/net/eth0/address) -2)
@@ -181,6 +182,7 @@ case "$FIRMWARE" in
openmesh,a62)
ath10kcal_extract "0:ART" 20480 12064
;;
+ zyxel,nbg6617 |\
zyxel,wre6606)
ath10kcal_extract "ART" 20480 12064
ath10kcal_patch_mac_crc $(macaddr_add $(cat /sys/class/net/eth0/address) -1)
diff --git a/target/linux/ipq40xx/base-files/lib/preinit/05_set_iface_mac_ipq40xx.sh b/target/linux/ipq40xx/base-files/lib/preinit/05_set_iface_mac_ipq40xx.sh
index 1acd7366c81f7c70ef9018d97a833e4d355e8119..44e81ca366dd57d3d5d7fbb9065254925e94061a 100644
--- a/target/linux/ipq40xx/base-files/lib/preinit/05_set_iface_mac_ipq40xx.sh
+++ b/target/linux/ipq40xx/base-files/lib/preinit/05_set_iface_mac_ipq40xx.sh
@@ -8,6 +8,10 @@ preinit_set_mac_address() {
mac_lan=$(get_mac_binary "/sys/bus/i2c/devices/0-0050/eeprom" 102)
[ -n "$mac_lan" ] && ip link set dev eth0 address "$mac_lan"
;;
+ zyxel,nbg6617)
+ base_mac=$(cat /sys/class/net/eth0/address)
+ ip link set dev eth0 address $(macaddr_add "$base_mac" +2)
+ ip link set dev eth1 address $(macaddr_add "$base_mac" +3)
esac
}
diff --git a/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh b/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh
new file mode 100644
index 0000000000000000000000000000000000000000..578ddbe4c4f6e91d925ea3a0de9e060daac82e72
--- /dev/null
+++ b/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+set_preinit_iface() {
+ . /lib/functions.sh
+
+ case $(board_name) in
+ asus,rt-ac58u| \
+ avm,fritzbox-4040| \
+ glinet,gl-b1300| \
+ meraki,mr33| \
+ zyxel,nbg6617)
+ ifname=eth0
+ ;;
+ *)
+ ;;
+ esac
+}
+
+boot_hook_add preinit_main set_preinit_iface
diff --git a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
index 4096e127ea9eaa8106475a3143b0b2ea796b5c7c..0e29302465fb5fca6f2a2194c751728f492053d5 100644
--- a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
@@ -29,6 +29,21 @@ EOF
return 0;
}
+zyxel_do_upgrade() {
+ local tar_file="$1"
+
+ local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$')
+ board_dir=${board_dir%/}
+
+ tar Oxf $tar_file ${board_dir}/kernel | mtd write - kernel
+
+ if [ "$SAVE_CONFIG" -eq 1 ]; then
+ tar Oxf $tar_file ${board_dir}/root | mtd -j "$CONF_TAR" write - rootfs
+ else
+ tar Oxf $tar_file ${board_dir}/root | mtd write - rootfs
+ fi
+}
+
platform_do_upgrade() {
case "$(board_name)" in
8dev,jalapeno)
@@ -48,6 +63,9 @@ platform_do_upgrade() {
CI_KERNPART="part.safe"
nand_do_upgrade "$1"
;;
+ zyxel,nbg6617)
+ zyxel_do_upgrade "$1"
+ ;;
*)
default_do_upgrade "$ARGV"
;;
diff --git a/target/linux/ipq40xx/files-4.14/arch/arm/boot/dts/qcom-ipq4018-nbg6617.dts b/target/linux/ipq40xx/files-4.14/arch/arm/boot/dts/qcom-ipq4018-nbg6617.dts
new file mode 100644
index 0000000000000000000000000000000000000000..d7f8c5955caee15d373a342b75c8c1947f5b8022
--- /dev/null
+++ b/target/linux/ipq40xx/files-4.14/arch/arm/boot/dts/qcom-ipq4018-nbg6617.dts
@@ -0,0 +1,321 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * 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 "qcom-ipq4019.dtsi"
+#include "qcom-ipq4019-bus.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/soc/qcom,tcsr.h>
+
+/ {
+ model = "ZyXEL NBG6617";
+ compatible = "zyxel,nbg6617", "qcom,ipq4019";
+
+ chosen {
+ /*
+ * the vendor u-boot adds root and mtdparts cmdline parameters
+ * which we don't want... but we have to overwrite them or else
+ * the kernel will take them at face value.
+ */
+ bootargs-append = " mtdparts= root=31:13";
+ };
+
+ aliases {
+ led-boot = &power;
+ led-failsafe = &power;
+ led-running = &power;
+ led-upgrade = &power;
+ };
+
+ soc {
+ mdio@90000 {
+ status = "okay";
+ };
+
+ ess-psgmii@98000 {
+ status = "okay";
+ };
+
+ tcsr@1949000 {
+ compatible = "qcom,tcsr";
+ reg = <0x1949000 0x100>;
+ qcom,wifi_glb_cfg = <TCSR_WIFI_GLB_CFG>;
+ };
+
+ tcsr@194b000 {
+ compatible = "qcom,tcsr";
+ reg = <0x194b000 0x100>;
+ qcom,usb-hsphy-mode-select = <TCSR_USB_HSPHY_HOST_MODE>;
+ };
+
+ ess_tcsr@1953000 {
+ compatible = "qcom,tcsr";
+ reg = <0x1953000 0x1000>;
+ qcom,ess-interface-select = <TCSR_ESS_PSGMII>;
+ };
+
+ tcsr@1957000 {
+ compatible = "qcom,tcsr";
+ reg = <0x1957000 0x100>;
+ qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
+ };
+
+ usb2@60f8800 {
+ status = "okay";
+ };
+
+ serial@78af000 {
+ pinctrl-0 = <&serial_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+
+ usb3@8af8800 {
+ status = "okay";
+ };
+
+ crypto@8e3a000 {
+ status = "okay";
+ };
+
+ watchdog@b017000 {
+ status = "okay";
+ };
+
+ ess-switch@c000000 {
+ status = "okay";
+ };
+
+ edma@c080000 {
+ status = "okay";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ wlan {
+ label = "wlan";
+ gpios = <&tlmm 2 GPIO_ACTIVE_HIGH>;
+ linux,code = <KEY_RFKILL>;
+ linux,input-type = <EV_SW>;
+ };
+
+ wps {
+ label = "wps";
+ gpios = <&tlmm 63 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ };
+
+ reset {
+ label = "reset";
+ gpios = <&tlmm 4 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&led_pins>;
+ pinctrl-names = "default";
+
+ power: power {
+ label = "nbg6617:green:power";
+ gpios = <&tlmm 3 GPIO_ACTIVE_HIGH>;
+ };
+
+ usb {
+ label = "nbg6617:green:usb";
+ gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ wlan2G {
+ label = "nbg6617:green:wlan2G";
+ gpios = <&tlmm 58 GPIO_ACTIVE_HIGH>;
+ };
+
+ wlan5G {
+ label = "nbg6617:green:wlan5G";
+ gpios = <&tlmm 5 GPIO_ACTIVE_HIGH>;
+ };
+
+ wps {
+ label = "nbg6617:green:wps";
+ gpios = <&tlmm 1 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&tlmm {
+ serial_pins: serial_pinmux {
+ mux {
+ pins = "gpio60", "gpio61";
+ function = "blsp_uart0";
+ bias-disable;
+ };
+ };
+ spi_0_pins: spi_0_pinmux {
+ mux {
+ function = "blsp_spi0";
+ pins = "gpio55", "gpio56", "gpio57";
+ drive-strength = <12>;
+ bias-disable;
+ };
+
+ mux_cs {
+ function = "gpio";
+ pins = "gpio54";
+ drive-strength = <2>;
+ bias-disable;
+ output-low;
+ };
+ };
+ led_pins: led_pinmux {
+ mux {
+ pins = "gpio0", "gpio1", "gpio3", "gpio5", "gpio58";
+ drive-strength = <0x8>;
+ bias-disable;
+ output-low;
+ };
+ };
+};
+
+&spi_0 { /* BLSP1 QUP1 */
+ pinctrl-0 = <&spi_0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
+
+ mx25l25635f@0 {
+ compatible = "mx25l25635f", "jedec,spi-nor";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ spi-max-frequency = <24000000>;
+ status = "okay";
+ m25p,fast-read;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition0@0 {
+ label = "SBL1";
+ reg = <0x00000000 0x00040000>;
+ read-only;
+ };
+ partition1@40000 {
+ label = "MIBIB";
+ reg = <0x00040000 0x00020000>;
+ read-only;
+ };
+ partition2@60000 {
+ label = "QSEE";
+ reg = <0x00060000 0x00060000>;
+ read-only;
+ };
+ partition3@c0000 {
+ label = "CDT";
+ reg = <0x000c0000 0x00010000>;
+ read-only;
+ };
+ partition4@d0000 {
+ label = "DDRPARAMS";
+ reg = <0x000d0000 0x00010000>;
+ read-only;
+ };
+ partition5@e0000 {
+ label = "APPSBL"; /* u-boot */
+ reg = <0x000e0000 0x00080000>;
+ /* U-Boot Standalone App "zloader" is located at 0x64000 */
+ read-only;
+ };
+ partition6@160000 {
+ label = "APPSBLENV"; /* u-boot env */
+ reg = <0x00160000 0x00010000>;
+ };
+ partition7@170000 {
+ /* make a backup of this partition! */
+ label = "ART";
+ reg = <0x00170000 0x00010000>;
+ read-only;
+ };
+ partition8@180000 {
+ label = "kernel";
+ reg = <0x00180000 0x00400000>;
+ };
+ partition9@580000 {
+ label = "dualflag";
+ reg = <0x00580000 0x00010000>;
+ read-only;
+ };
+ partition10@590000 {
+ label = "header";
+ reg = <0x00590000 0x00010000>;
+ };
+ partition11@5a0000 {
+ label = "romd";
+ reg = <0x005a0000 0x00100000>;
+ read-only;
+ };
+ partition12@6a0000 {
+ label = "not_root_data";
+ /*
+ * for some strange reason, someone at ZyXEL
+ * had the "great" idea to put the rootfs_data
+ * in front of rootfs... Don't do that!
+ * As a result this one, full MebiByte remains
+ * unused.
+ */
+ reg = <0x006a0000 0x00100000>;
+ };
+ partition13@7a0000 {
+ label = "rootfs";
+ reg = <0x007a0000 0x01860000>;
+ };
+ };
+ };
+};
+
+&cryptobam {
+ status = "okay";
+};
+
+&blsp_dma {
+ status = "okay";
+};
+
+&wifi0 {
+ status = "okay";
+};
+
+&wifi1 {
+ status = "okay";
+};
+
+&usb3_ss_phy {
+ status = "okay";
+};
+
+&usb3_hs_phy {
+ status = "okay";
+};
+
+&usb2_hs_phy {
+ status = "okay";
+};
diff --git a/target/linux/ipq40xx/image/Makefile b/target/linux/ipq40xx/image/Makefile
index 38600cf979242142aa08c30163e63d911f0ddb63..d1ee1004fddce6cf6007259229d8eee5b5b2ea3b 100644
--- a/target/linux/ipq40xx/image/Makefile
+++ b/target/linux/ipq40xx/image/Makefile
@@ -1,6 +1,8 @@
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/image.mk
+DEVICE_VARS += RAS_BOARD RAS_ROOTFS_SIZE RAS_VERSION
+
define Device/Default
PROFILES := Default
KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts)
@@ -205,6 +207,26 @@ define Device/qcom_ap-dk04.1-c1
endef
TARGET_DEVICES += qcom_ap-dk04.1-c1
+define Device/zyxel_nbg6617
+ $(call Device/FitImageLzma)
+ DEVICE_DTS := qcom-ipq4018-nbg6617
+ DEVICE_TITLE := ZyXEL NBG6617
+ ROOTFS_SIZE := 24960k
+ RAS_BOARD := NBG6617
+ RAS_ROOTFS_SIZE := 19840k
+ RAS_VERSION := "$(VERSION_DIST) $(REVISION)"
+ IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata
+ IMAGES := sysupgrade.bin factory.bin
+# The ZyXEL firmware allows flashing thru the web-gui only when the rootfs is
+# at least as large as the one of the initial firmware image (not the current
+# one on the device). This only applies to the Web-UI, the bootlaoder ignores
+# this minimum-size. However, the larger image can be flashed both ways.
+ IMAGE/factory.bin := append-rootfs | pad-rootfs | check-size $$$$(ROOTFS_SIZE) | make-ras
+ IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | check-size $$$$(ROOTFS_SIZE) | sysupgrade-tar rootfs=$$$$@ | append-metadata
+ DEVICE_PACKAGES := ipq-wifi-zyxel_nbg6617 uboot-envtools
+endef
+TARGET_DEVICES += zyxel_nbg6617
+
define Device/zyxel_wre6606
$(call Device/FitImage)
DEVICE_TITLE := ZyXEL WRE6606
diff --git a/target/linux/ipq40xx/patches-4.14/069-arm-boot-add-dts-files.patch b/target/linux/ipq40xx/patches-4.14/069-arm-boot-add-dts-files.patch
index 3aa368be8381d9c48aefccbe6d4cc768b00dc41e..8066f986a4e030c9c8fe0ec4438e92d30daa77f0 100644
--- a/target/linux/ipq40xx/patches-4.14/069-arm-boot-add-dts-files.patch
+++ b/target/linux/ipq40xx/patches-4.14/069-arm-boot-add-dts-files.patch
@@ -10,7 +10,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
-@@ -697,7 +697,19 @@ dtb-$(CONFIG_ARCH_QCOM) += \
+@@ -697,7 +697,20 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-apq8074-dragonboard.dtb \
qcom-apq8084-ifc6540.dtb \
qcom-apq8084-mtp.dtb \
@@ -19,6 +19,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
+ qcom-ipq4018-ex6150v2.dtb \
+ qcom-ipq4018-fritz4040.dtb \
+ qcom-ipq4018-jalapeno.dtb \
++ qcom-ipq4018-nbg6617.dtb \
+ qcom-ipq4018-rt-ac58u.dtb \
+ qcom-ipq4018-wre6606.dtb \
qcom-ipq4019-ap.dk01.1-c1.dtb \
diff --git a/target/linux/ipq40xx/patches-4.14/303-spi-nor-enable-4B-opcodes-for-mx25l25635f.patch b/target/linux/ipq40xx/patches-4.14/303-spi-nor-enable-4B-opcodes-for-mx25l25635f.patch
new file mode 100644
index 0000000000000000000000000000000000000000..7c513a6ad8ec817bf388c67e1181f08982888fa5
--- /dev/null
+++ b/target/linux/ipq40xx/patches-4.14/303-spi-nor-enable-4B-opcodes-for-mx25l25635f.patch
@@ -0,0 +1,64 @@
+Index: linux-4.14.50/drivers/mtd/spi-nor/spi-nor.c
+===================================================================
+--- linux-4.14.50.orig/drivers/mtd/spi-nor/spi-nor.c
++++ linux-4.14.50/drivers/mtd/spi-nor/spi-nor.c
+@@ -1025,6 +1025,7 @@ static const struct flash_info spi_nor_i
+ { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
+ { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
+ { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
++ { "mx25l25635f", INFO(0xc22019, 0, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+ { "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_4B_OPCODES) },
+ { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
+ { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+@@ -1189,11 +1190,12 @@ static const struct flash_info spi_nor_i
+ { },
+ };
+
+-static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
++static const struct flash_info *spi_nor_read_id(struct spi_nor *nor,
++ const char *name)
+ {
+ int tmp;
+ u8 id[SPI_NOR_MAX_ID_LEN];
+- const struct flash_info *info;
++ const struct flash_info *info, *first_match = NULL;
+
+ tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
+ if (tmp < 0) {
+@@ -1204,10 +1206,16 @@ static const struct flash_info *spi_nor_
+ for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) {
+ info = &spi_nor_ids[tmp];
+ if (info->id_len) {
+- if (!memcmp(info->id, id, info->id_len))
+- return &spi_nor_ids[tmp];
++ if (!memcmp(info->id, id, info->id_len)) {
++ if (!name || !strcmp(name, info->name))
++ return info;
++ if (!first_match)
++ first_match = info;
++ }
+ }
+ }
++ if (first_match)
++ return first_match;
+ dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n",
+ id[0], id[1], id[2]);
+ return ERR_PTR(-ENODEV);
+@@ -2667,7 +2675,7 @@ int spi_nor_scan(struct spi_nor *nor, co
+ info = spi_nor_match_id(name);
+ /* Try to auto-detect if chip name wasn't specified or not found */
+ if (!info)
+- info = spi_nor_read_id(nor);
++ info = spi_nor_read_id(nor, NULL);
+ if (IS_ERR_OR_NULL(info))
+ return -ENOENT;
+
+@@ -2678,7 +2686,7 @@ int spi_nor_scan(struct spi_nor *nor, co
+ if (name && info->id_len) {
+ const struct flash_info *jinfo;
+
+- jinfo = spi_nor_read_id(nor);
++ jinfo = spi_nor_read_id(nor, name);
+ if (IS_ERR(jinfo)) {
+ return PTR_ERR(jinfo);
+ } else if (jinfo != info) {
From: David Bauer <mail@david-bauer.net>
Date: Wed, 22 Aug 2018 17:30:44 +0200
Subject: build: add mkrasimage
The current make-ras.sh image generation script for the ZyXEL NBG6617
has portability issues with bash. Because of this, factory images are
currently not built correctly by the OpenWRT buildbots.
This commit replaces the make-ras.sh by C-written mkrasimage.
The new mkrasimage is also compatible with other ZyXEL devices using
the ras image-format.
This is not tested with the NBG6616 but it correctly builds the
header for ZyXEL factory image.
Signed-off-by: David Bauer <mail@david-bauer.net>
diff --git a/include/image-commands.mk b/include/image-commands.mk
index 28b39c310e499caea4fe8a6d9ad6dceb5d95363b..552d8db1cbacf533c12d0d8e2e5cffbe5591adb4 100644
--- a/include/image-commands.mk
+++ b/include/image-commands.mk
@@ -49,17 +49,17 @@ define Build/eva-image
mv $@.new $@
endef
-define Build/make-ras
+define Build/zyxel-ras-image
let \
newsize="$(subst k,* 1024,$(RAS_ROOTFS_SIZE))"; \
- $(TOPDIR)/scripts/make-ras.sh \
- --board $(RAS_BOARD) \
- --version $(RAS_VERSION) \
- --kernel $(call param_get_default,kernel,$(1),$(IMAGE_KERNEL)) \
- --rootfs $@ \
- --rootfssize $$newsize \
- $@.new
- @mv $@.new $@
+ $(STAGING_DIR_HOST)/bin/mkrasimage \
+ -b $(RAS_BOARD) \
+ -v $(RAS_VERSION) \
+ -r $@ \
+ -s $$newsize \
+ -o $@.new \
+ $(if $(findstring separate-kernel,$(word 1,$(1))),-k $(IMAGE_KERNEL)) \
+ && mv $@.new $@
endef
define Build/netgear-chk
diff --git a/scripts/make-ras.sh b/scripts/make-ras.sh
deleted file mode 100755
index ccddaa0016b0c926d4737abb5757e7212b0a1157..0000000000000000000000000000000000000000
--- a/scripts/make-ras.sh
+++ /dev/null
@@ -1,196 +0,0 @@
-#!/usr/bin/env bash
-#
-# --- ZyXEL header format ---
-# Original Version by Benjamin Berg <benjamin@sipsolutions.net>
-#
-# The firmware image prefixed with a header (which is written into the MTD device).
-# The header is one erase block (~64KiB) in size, but the checksum only convers the
-# first 2KiB. Padding is 0xff. All integers are in big-endian.
-#
-# The checksum is always a 16-Bit System V checksum (sum -s) stored in a 32-Bit integer.
-#
-# 4 bytes: checksum of the rootfs image
-# 4 bytes: length of the contained rootfs image file (big endian)
-# 32 bytes: Firmware Version string (NUL terminated, 0xff padded)
-# 4 bytes: checksum over the header partition (big endian - see below)
-# 32 bytes: Model (e.g. "NBG6617", NUL termiated, 0xff padded)
-# 4 bytes: checksum of the kernel partition
-# 4 bytes: length of the contained kernel image file (big endian)
-# rest: 0xff padding
-#
-# The checksums are calculated by adding up all bytes and if a 16bit
-# overflow occurs, one is added and the sum is masked to 16 bit:
-# csum = csum + databyte; if (csum > 0xffff) { csum += 1; csum &= 0xffff };
-# Should the file have an odd number of bytes then the byte len-0x800 is
-# used additionally.
-#
-# The checksum for the header is calculated over the first 2048 bytes with
-# the rootfs image checksum as the placeholder during calculation.
-#
-# The header is padded with 0xff to the erase block size of the device.
-#
-board=""
-version=""
-kernel=""
-rootfs=""
-outfile=""
-err=""
-
-while [ "$1" ]; do
- case "$1" in
- "--board")
- board="$2"
- shift
- shift
- continue
- ;;
- "--version")
- version="$2"
- shift
- shift
- continue
- ;;
- "--kernel")
- kernel="$2"
- shift
- shift
- continue
- ;;
- "--rootfs")
- rootfs="$2"
- shift
- shift
- continue
- ;;
- "--rootfssize")
- rootfssize="$2"
- shift
- shift
- continue
- ;;
- *)
- if [ ! "$outfile" ]; then
- outfile=$1
- shift
- continue
- fi
- ;;
- esac
-done
-
-if [ ! -n "$board" -o ! -n "$version" -o ! -r "$kernel" -o ! -r "$rootfs" -o ! "$rootfssize" -o ! "$outfile" ]; then
- echo "syntax: $0 [--board ras-boardname] [--version ras-version] [--kernel kernelimage] [--rootfs rootfs] out"
- exit 1
-fi
-
-rootfs_len=$(wc -c < "$rootfs")
-
-if [ "$rootfs_len" -lt "$rootfssize" ]; then
- dd if=$rootfs of=$rootfs.new bs=$rootfssize conv=sync
- mv $rootfs.new $rootfs
-fi
-
-if [ ${#version} -ge 28 ]; then
- echo "version: '$version' is too long"
- exit 1
-fi
-
-tmpdir="$( mktemp -d 2> /dev/null )"
-if [ -z "$tmpdir" ]; then
- # try OSX signature
- tmpdir="$( mktemp -t 'ubitmp' -d )"
-fi
-
-if [ -z "$tmpdir" ]; then
- exit 1
-fi
-
-to_be() {
- local val="$1"
- local size="$2"
-
- case "$size" in
- 4)
- echo $(( "$val" >> 24 | ("$val" & 0xff0000) >> 8 | ("$val" & 0xff00) << 8 | ("$val" & 0xff) << 24 ))
- ;;
- 2)
- echo $(( "$val" >> 8 | ("$val" & 0xff) << 8))
- ;;
- esac
-}
-
-checksum_file() {
- local file=$1
-
- # ZyXEL seems to use System V sum mode... Now this is classy, who would have thought?!
- echo $(sum -s ${file} | cut -f1 -d" ")
-}
-
-append_bin() {
- local val=$1
- local size=$2
- local file=$3
-
- while [ "$size" -ne 0 ]; do
- printf \\$(printf %o $(("$val" & 0xff))) >> "$file"
- val=$(($val >> 8))
- let size-=1
- done
- return
-}
-
-tf=${tmpdir}/out
-pad=$(printf '%0.1s' $(printf "\xff"){1..64})
-
-rootfs_header_file="$tmpdir/rootfs_header"
-rootfs_chksum=$(to_be $(checksum_file ${rootfs}) 4)
-rootfs_len=$(to_be $(wc -c < "$rootfs") 4)
-
-versionpadlen=$(( 32 - ( ${#version} + 1) ))
-
-# 4 bytes: checksum of the rootfs image
-append_bin "$rootfs_chksum" 4 "$rootfs_header_file"
-# 4 bytes: length of the contained rootfs image file (big endian)
-append_bin "$rootfs_len" 4 "$rootfs_header_file"
-# 32 bytes: Firmware Version string (NUL terminated, 0xff padded)
-printf "%s\x00%.*s" "$version" "$versionpadlen" "$pad" >> "$rootfs_header_file"
-
-kernel_header_file="$tmpdir/kernel_header"
-kernel_chksum=$(to_be $(checksum_file ${kernel}) 4)
-kernel_len=$(to_be $(wc -c < "$kernel") 4)
-
-# 4 bytes: checksum of the kernel image
-append_bin "$kernel_chksum" 4 "$kernel_header_file"
-# 4 bytes: length of the contained kernel image file (big endian)
-append_bin "$kernel_len" 4 "$kernel_header_file"
-
-board_header_file="$tmpdir/board_header"
-board_file="$tmpdir/board"
-boardpadlen=$(( 64 - ( ${#board} + 1) ))
-# 32 bytes: Model (e.g. "NBG6617", NUL termiated, 0xff padded)
-printf "%s\x00%.*s" "$board" "$boardpadlen" "$pad" > "$board_file"
-cat "$kernel_header_file" >> "$board_file"
-printf "%.12s" "$pad" >> "$board_file"
-# rest: 0xff padding
-for i in {1..511}; do
- printf "%s%s" "$pad" "$pad" >> "$board_file"
-done
-
-tmp_board_file="$tmpdir/tmp_board_file"
-cat "$rootfs_header_file" > "$tmp_board_file"
-
-# The checksum for the header is calculated over the first 2048 bytes with
-# the rootfs image checksum as the placeholder during calculation.
-append_bin "$rootfs_chksum" 4 "$tmp_board_file"
-cat "$board_file" >> "$tmp_board_file"
-
-truncate -s 2048 $tmp_board_file
-board_chksum=$(to_be $(checksum_file ${tmp_board_file}) 4)
-
-# 4 bytes: checksum over the header partition (big endian)
-append_bin "$board_chksum" 4 "$board_header_file"
-cat "$board_file" >> "$board_header_file"
-
-cat "$rootfs_header_file" "$board_header_file" "$rootfs" "$kernel" > "$outfile"
-
-rm -rf "$tmpdir"
diff --git a/target/linux/ar71xx/image/generic.mk b/target/linux/ar71xx/image/generic.mk
index 640557532c8a02f37bc6f84ade8cb34e7172162d..4568b656219419e9ca1156c6716bd2124074cb32 100644
--- a/target/linux/ar71xx/image/generic.mk
+++ b/target/linux/ar71xx/image/generic.mk
@@ -1086,8 +1086,12 @@ define Device/NBG6616
IMAGE_SIZE := 15323k
MTDPARTS := spi0.0:192k(u-boot)ro,64k(env)ro,64k(RFdata)ro,384k(zyxel_rfsd),384k(romd),64k(header),2048k(kernel),13184k(rootfs),15232k@0x120000(firmware)
CMDLINE += mem=128M
- IMAGES := sysupgrade.bin
+ RAS_BOARD := NBG6616
+ RAS_ROOTFS_SIZE := 14464k
+ RAS_VERSION := "$(VERSION_DIST) $(REVISION)"
+ IMAGES := factory.bin sysupgrade.bin
KERNEL := kernel-bin | patch-cmdline | lzma | uImage lzma | jffs2 boot/vmlinux.lzma.uImage
+ IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | pad-rootfs | pad-to 64k | check-size $$$$(IMAGE_SIZE) | zyxel-ras-image
IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | pad-rootfs | check-size $$$$(IMAGE_SIZE)
# We cannot currently build a factory image. It is the sysupgrade image
# prefixed with a header (which is actually written into the MTD device).
diff --git a/target/linux/ipq40xx/image/Makefile b/target/linux/ipq40xx/image/Makefile
index d1ee1004fddce6cf6007259229d8eee5b5b2ea3b..5cd11cae237b4658906652967d8120bd0dc080a8 100644
--- a/target/linux/ipq40xx/image/Makefile
+++ b/target/linux/ipq40xx/image/Makefile
@@ -221,7 +221,7 @@ define Device/zyxel_nbg6617
# at least as large as the one of the initial firmware image (not the current
# one on the device). This only applies to the Web-UI, the bootlaoder ignores
# this minimum-size. However, the larger image can be flashed both ways.
- IMAGE/factory.bin := append-rootfs | pad-rootfs | check-size $$$$(ROOTFS_SIZE) | make-ras
+ IMAGE/factory.bin := append-rootfs | pad-rootfs | pad-to 64k | check-size $$$$(ROOTFS_SIZE) | zyxel-ras-image separate-kernel
IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | check-size $$$$(ROOTFS_SIZE) | sysupgrade-tar rootfs=$$$$@ | append-metadata
DEVICE_PACKAGES := ipq-wifi-zyxel_nbg6617 uboot-envtools
endef
diff --git a/target/linux/ipq806x/image/Makefile b/target/linux/ipq806x/image/Makefile
index 2902af3231a87592e9c040e7e7e1e4e1958a01a5..a7f740ff62e05c7f6f24caa6da538302abee8d8f 100644
--- a/target/linux/ipq806x/image/Makefile
+++ b/target/linux/ipq806x/image/Makefile
@@ -67,7 +67,8 @@ define Device/ZyXELImage
KERNEL_SUFFIX := -uImage
KERNEL = kernel-bin | append-dtb | uImage none | pad-to $${KERNEL_SIZE}
KERNEL_NAME := zImage
- IMAGES := sysupgrade.bin mmcblk0p5-rootfs.bin mmcblk0p4-kernel.bin
+ IMAGES := factory.bin sysupgrade.bin mmcblk0p5-rootfs.bin mmcblk0p4-kernel.bin
+ IMAGE/factory.bin := append-rootfs | pad-rootfs | pad-to $$$$(BLOCKSIZE) | zyxel-ras-image separate-kernel
IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-to $$$${BLOCKSIZE} | sysupgrade-tar rootfs=$$$$@ | append-metadata
IMAGE/mmcblk0p5-rootfs.bin := append-rootfs | pad-rootfs | pad-to $$$${BLOCKSIZE}
IMAGE/mmcblk0p4-kernel.bin := append-kernel
@@ -245,6 +246,9 @@ define Device/zyxel_nbg6817
KERNEL_SIZE := 4096k
BLOCKSIZE := 64k
BOARD_NAME := nbg6817
+ RAS_BOARD := NBG6817
+ RAS_ROOTFS_SIZE := 20934k
+ RAS_VERSION := "V1.99(OWRT.9999)C0"
SUPPORTED_DEVICES += nbg6817
DEVICE_TITLE := ZyXEL NBG6817
DEVICE_PACKAGES := ath10k-firmware-qca9984 e2fsprogs kmod-fs-ext4 losetup
diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile
index 4b4af999088455e3d9231b227fecfa71c8284b2f..a6379e35eb01f1cbbe2b1ece3fc9eb20bcd68d90 100644
--- a/tools/firmware-utils/Makefile
+++ b/tools/firmware-utils/Makefile
@@ -70,6 +70,7 @@ define Host/Compile
$(call cc,fix-u-media-header cyg_crc32,-Wall)
$(call cc,hcsmakeimage bcmalgo)
$(call cc,mkporayfw, -Wall)
+ $(call cc,mkrasimage, --std=gnu99)
$(call cc,mkhilinkfw, -lcrypto)
$(call cc,mkdcs932, -Wall)
$(call cc,mkheader_gemtek,-lz)
diff --git a/tools/firmware-utils/src/mkrasimage.c b/tools/firmware-utils/src/mkrasimage.c
new file mode 100644
index 0000000000000000000000000000000000000000..8eee29cc086a04104b51e263aeac0e73340056ca
--- /dev/null
+++ b/tools/firmware-utils/src/mkrasimage.c
@@ -0,0 +1,459 @@
+/*
+ * --- ZyXEL header format ---
+ * Original Version by Benjamin Berg <benjamin@sipsolutions.net>
+ * C implementation based on generation-script by Christian Lamparter <chunkeey@gmail.com>
+ *
+ * The firmware image prefixed with a header (which is written into the MTD device).
+ * The header is one erase block (~64KiB) in size, but the checksum only convers the
+ * first 2KiB. Padding is 0xff. All integers are in big-endian.
+ *
+ * The checksum is always a 16-Bit System V checksum (sum -s) stored in a 32-Bit integer.
+ *
+ * 4 bytes: checksum of the rootfs image
+ * 4 bytes: length of the contained rootfs image file (big endian)
+ * 32 bytes: Firmware Version string (NUL terminated, 0xff padded)
+ * 4 bytes: checksum over the header partition (big endian - see below)
+ * 64 bytes: Model (e.g. "NBG6617", NUL termiated, 0xff padded)
+ * 4 bytes: checksum of the kernel partition
+ * 4 bytes: length of the contained kernel image file (big endian)
+ * rest: 0xff padding (To erase block size)
+ *
+ * The kernel partition checksum and length is not used for every device.
+ * If it's notused, pad those 8 bytes with 0xFF.
+ *
+ * The checksums are calculated by adding up all bytes and if a 16bit
+ * overflow occurs, one is added and the sum is masked to 16 bit:
+ * csum = csum + databyte; if (csum > 0xffff) { csum += 1; csum &= 0xffff };
+ * Should the file have an odd number of bytes then the byte len-0x800 is
+ * used additionally.
+ *
+ * The checksum for the header is calculated over the first 2048 bytes with
+ * the rootfs image checksum as the placeholder during calculation.
+ *
+ * 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 <fcntl.h>
+#include <getopt.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <arpa/inet.h>
+
+#define VERSION_STRING_LEN 31
+#define ROOTFS_HEADER_LEN 40
+
+#define KERNEL_HEADER_LEN 8
+
+#define BOARD_NAME_LEN 64
+#define BOARD_HEADER_LEN 68
+
+#define HEADER_PARTITION_CALC_LENGTH 2048
+#define HEADER_PARTITION_LENGTH 0x10000
+
+struct file_info {
+ char *name; /* name of the file */
+ char *data; /* file content */
+ size_t size; /* length of the file */
+};
+
+static char *progname;
+
+static char *board_name = 0;
+static char *version_name = 0;
+static unsigned int rootfs_size = 0;
+
+static struct file_info kernel = { NULL, NULL, 0 };
+static struct file_info rootfs = { NULL, NULL, 0 };
+static struct file_info rootfs_out = { NULL, NULL, 0 };
+static struct file_info out = { NULL, NULL, 0 };
+
+#define ERR(fmt, ...) do { \
+ fprintf(stderr, "[%s] *** error: " fmt "\n", \
+ progname, ## __VA_ARGS__ ); \
+} while (0)
+
+void map_file(struct file_info *finfo)
+{
+ struct stat file_stat = {0};
+ int fd;
+
+ fd = open(finfo->name, O_RDONLY, (mode_t)0600);
+ if (fd == -1) {
+ ERR("Error while opening file %s.", finfo->name);
+ exit(EXIT_FAILURE);
+ }
+
+ if (fstat(fd, &file_stat) == -1) {
+ ERR("Error getting file size for %s.", finfo->name);
+ exit(EXIT_FAILURE);
+ }
+
+ finfo->size = file_stat.st_size;
+ finfo->data = mmap(0, finfo->size, PROT_READ, MAP_SHARED, fd, 0);
+
+ if (finfo->data == MAP_FAILED) {
+ ERR("Error mapping file %s.", finfo->name);
+ exit(EXIT_FAILURE);
+ }
+
+ close(fd);
+}
+
+void unmap_file(struct file_info *finfo)
+{
+ if(munmap(finfo->data, finfo->size) == -1) {
+ ERR("Error unmapping file %s.", finfo->name);
+ exit(EXIT_FAILURE);
+ }
+}
+
+void write_file(struct file_info *finfo)
+{
+ FILE *fout = fopen(finfo->name, "w");
+
+ fwrite(finfo->data, finfo->size, 1, fout);
+
+ if (ferror(fout)) {
+ ERR("Wanted to write, but something went wrong.");
+ exit(EXIT_FAILURE);
+ }
+
+ fclose(fout);
+}
+
+void usage(int status)
+{
+ FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
+
+ fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);
+ fprintf(stream,
+ "\n"
+ "Options:\n"
+ " -k <kernel> path for kernel image\n"
+ " -r <rootfs> path for rootfs image\n"
+ " -s <rfssize> size of output rootfs\n"
+ " -v <version> version string\n"
+ " -b <boardname> name of board to generate image for\n"
+ " -o <out_name> name of output image\n"
+ " -h show this screen\n"
+ );
+
+ exit(status);
+}
+
+static int sysv_chksm(const unsigned char *data, int size)
+{
+ int r;
+ int checksum;
+ unsigned int s = 0; /* The sum of all the input bytes, modulo (UINT_MAX + 1). */
+
+
+ for (int i = 0; i < size; i++) {
+ s += data[i];
+ }
+
+ r = (s & 0xffff) + ((s & 0xffffffff) >> 16);
+ checksum = (r & 0xffff) + (r >> 16);
+
+ return checksum;
+}
+
+static int zyxel_chksm(const unsigned char *data, int size)
+{
+ return htonl(sysv_chksm(data, size));
+}
+
+char *generate_rootfs_header(struct file_info filesystem, char *version)
+{
+ size_t version_string_length;
+ unsigned int chksm, size;
+ char *rootfs_header;
+ size_t ptr = 0;
+
+ rootfs_header = malloc(ROOTFS_HEADER_LEN);
+ if (!rootfs_header) {
+ ERR("Couldn't allocate memory for rootfs header!");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Prepare padding for firmware-version string here */
+ memset(rootfs_header, 0xff, ROOTFS_HEADER_LEN);
+
+ chksm = zyxel_chksm((const unsigned char *)filesystem.data, filesystem.size);
+ size = htonl(filesystem.size);
+
+ /* 4 bytes: checksum of the rootfs image */
+ memcpy(rootfs_header + ptr, &chksm, 4);
+ ptr += 4;
+
+ /* 4 bytes: length of the contained rootfs image file (big endian) */
+ memcpy(rootfs_header + ptr, &size, 4);
+ ptr += 4;
+
+ /* 32 bytes: Firmware Version string (NUL terminated, 0xff padded) */
+ version_string_length = strlen(version) <= VERSION_STRING_LEN ? strlen(version) : VERSION_STRING_LEN;
+ memcpy(rootfs_header + ptr, version, version_string_length);
+ ptr += version_string_length;
+ /* Add null-terminator */
+ rootfs_header[ptr] = 0x0;
+
+ return rootfs_header;
+}
+
+char *generate_kernel_header(struct file_info kernel)
+{
+ unsigned int chksm, size;
+ char *kernel_header;
+ size_t ptr = 0;
+
+ kernel_header = malloc(KERNEL_HEADER_LEN);
+ if (!kernel_header) {
+ ERR("Couldn't allocate memory for kernel header!");
+ exit(EXIT_FAILURE);
+ }
+
+ chksm = zyxel_chksm((const unsigned char *)kernel.data, kernel.size);
+ size = htonl(kernel.size);
+
+ /* 4 bytes: checksum of the kernel image */
+ memcpy(kernel_header + ptr, &chksm, 4);
+ ptr += 4;
+
+ /* 4 bytes: length of the contained kernel image file (big endian) */
+ memcpy(kernel_header + ptr, &size, 4);
+
+ return kernel_header;
+}
+
+unsigned int generate_board_header_checksum(char *kernel_hdr, char *rootfs_hdr, char *boardname)
+{
+ char *board_hdr_tmp;
+ unsigned int sum;
+ size_t ptr = 0;
+
+ /*
+ * The checksum of the board header is calculated over the first 2048 bytes of
+ * the header partition with the rootfs checksum used as a placeholder for then
+ * board checksum we calculate in this step. The checksum gained from this step
+ * is then used for the final board header partition.
+ */
+
+ board_hdr_tmp = malloc(HEADER_PARTITION_CALC_LENGTH);
+ if (!board_hdr_tmp) {
+ ERR("Couldn't allocate memory for temporary board header!");
+ exit(EXIT_FAILURE);
+ }
+ memset(board_hdr_tmp, 0xff, HEADER_PARTITION_CALC_LENGTH);
+
+ /* 40 bytes: RootFS header */
+ memcpy(board_hdr_tmp, rootfs_hdr, ROOTFS_HEADER_LEN);
+ ptr += ROOTFS_HEADER_LEN;
+
+ /* 4 bytes: RootFS checksum (BE) as placeholder for board-header checksum */
+ memcpy(board_hdr_tmp + ptr, rootfs_hdr, 4);
+ ptr += 4;
+
+ /* 32 bytes: Model (e.g. "NBG6617", NUL termiated, 0xff padded) */
+ memcpy(board_hdr_tmp + ptr, boardname, strlen(boardname));
+ ptr += strlen(boardname);
+ /* Add null-terminator */
+ board_hdr_tmp[ptr] = 0x0;
+ ptr = ROOTFS_HEADER_LEN + 4 + BOARD_NAME_LEN;
+
+ /* 8 bytes: Kernel header */
+ if (kernel_hdr)
+ memcpy(board_hdr_tmp + ptr, kernel_hdr, 8);
+
+ /* Calculate the checksum over the first 2048 bytes */
+ sum = zyxel_chksm((const unsigned char *)board_hdr_tmp, HEADER_PARTITION_CALC_LENGTH);
+ free(board_hdr_tmp);
+ return sum;
+}
+
+char *generate_board_header(char *kernel_hdr, char *rootfs_hdr, char *boardname)
+{
+ unsigned int board_checksum;
+ char *board_hdr;
+
+ board_hdr = malloc(BOARD_HEADER_LEN);
+ if (!board_hdr) {
+ ERR("Couldn't allocate memory for board header!");
+ exit(EXIT_FAILURE);
+ }
+ memset(board_hdr, 0xff, BOARD_HEADER_LEN);
+
+ /* 4 bytes: checksum over the header partition (big endian) */
+ board_checksum = generate_board_header_checksum(kernel_hdr, rootfs_hdr, boardname);
+ memcpy(board_hdr, &board_checksum, 4);
+
+ /* 32 bytes: Model (e.g. "NBG6617", NUL termiated, 0xff padded) */
+ memcpy(board_hdr + 4, boardname, strlen(boardname));
+ board_hdr[4 + strlen(boardname)] = 0x0;
+
+ return board_hdr;
+}
+
+int build_image()
+{
+ char *rootfs_header = NULL;
+ char *kernel_header = NULL;
+ char *board_header = NULL;
+
+ size_t ptr;
+
+ /* Load files */
+ if (kernel.name)
+ map_file(&kernel);
+ map_file(&rootfs);
+
+ /*
+ * Allocate memory and copy input rootfs for temporary output rootfs.
+ * This is important as we have to generate the rootfs checksum over the
+ * entire rootfs partition. As we might have to pad the partition to allow
+ * for flashing via ZyXEL's Web-GUI, we prepare the rootfs partition for the
+ * output image here (and also use it for calculating the rootfs checksum).
+ *
+ * The roofs padding has to be done with 0x00.
+ */
+ rootfs_out.data = calloc(rootfs_out.size, sizeof(char));
+ memcpy(rootfs_out.data, rootfs.data, rootfs.size);
+
+ /* Prepare headers */
+ rootfs_header = generate_rootfs_header(rootfs_out, version_name);
+ if (kernel.name)
+ kernel_header = generate_kernel_header(kernel);
+ board_header = generate_board_header(kernel_header, rootfs_header, board_name);
+
+ /* Prepare output file */
+ out.size = HEADER_PARTITION_LENGTH + rootfs_out.size;
+ if (kernel.name)
+ out.size += kernel.size;
+ out.data = malloc(out.size);
+ memset(out.data, 0xFF, out.size);
+
+ /* Build output image */
+ memcpy(out.data, rootfs_header, ROOTFS_HEADER_LEN);
+ memcpy(out.data + ROOTFS_HEADER_LEN, board_header, BOARD_HEADER_LEN);
+ if (kernel.name)
+ memcpy(out.data + ROOTFS_HEADER_LEN + BOARD_HEADER_LEN, kernel_header, KERNEL_HEADER_LEN);
+ ptr = HEADER_PARTITION_LENGTH;
+ memcpy(out.data + ptr, rootfs_out.data, rootfs_out.size);
+ ptr += rootfs_out.size;
+ if (kernel.name)
+ memcpy(out.data + ptr, kernel.data, kernel.size);
+
+ /* Write back output image */
+ write_file(&out);
+
+ /* Free allocated memory */
+ if (kernel.name)
+ unmap_file(&kernel);
+ unmap_file(&rootfs);
+ free(out.data);
+ free(rootfs_out.data);
+
+ free(rootfs_header);
+ if (kernel.name)
+ free(kernel_header);
+ free(board_header);
+
+ return 0;
+}
+
+int check_options()
+{
+ if (!rootfs.name) {
+ ERR("No rootfs filename supplied");
+ return -2;
+ }
+
+ if (!out.name) {
+ ERR("No output filename supplied");
+ return -3;
+ }
+
+ if (!board_name) {
+ ERR("No board-name supplied");
+ return -4;
+ }
+
+ if (!version_name) {
+ ERR("No version supplied");
+ return -5;
+ }
+
+ if (rootfs_size <= 0) {
+ ERR("Invalid rootfs size supplied");
+ return -6;
+ }
+
+ if (strlen(board_name) > 31) {
+ ERR("Board name is to long");
+ return -7;
+ }
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int ret;
+ progname = basename(argv[0]);
+ while (1) {
+ int c;
+
+ c = getopt(argc, argv, "b:k:o:r:s:v:h");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'b':
+ board_name = optarg;
+ break;
+ case 'h':
+ usage(EXIT_SUCCESS);
+ break;
+ case 'k':
+ kernel.name = optarg;
+ break;
+ case 'o':
+ out.name = optarg;
+ break;
+ case 'r':
+ rootfs.name = optarg;
+ break;
+ case 's':
+ sscanf(optarg, "%u", &rootfs_size);
+ break;
+ case 'v':
+ version_name = optarg;
+ break;
+ default:
+ usage(EXIT_FAILURE);
+ break;
+ }
+ }
+
+ ret = check_options();
+ if (ret)
+ usage(EXIT_FAILURE);
+
+ /* As ZyXEL Web-GUI only accept images with a rootfs equal or larger than the first firmware shipped
+ * for the device, we need to pad rootfs partition to this size. To perform further calculations, we
+ * decide the size of this part here. In case the rootfs we want to integrate in our image is larger,
+ * take it's size, otherwise the supplied size.
+ *
+ * Be careful! We rely on assertion of correct size to be performed beforehand. It is unknown if images
+ * with a to large rootfs are accepted or not.
+ */
+ rootfs_out.size = rootfs_size < rootfs.size ? rootfs.size : rootfs_size;
+ return build_image();
+}
From: David Bauer <mail@david-bauer.net>
Date: Sun, 4 Nov 2018 01:00:18 +0100
Subject: ipq40xx: fix NBG6617 LED mapping
The NBG6617's LEDs are wrongly identified in the 01_leds boardinit
script (board instead of boardname), thus referencing non-existant LEDs
in UCI.
Signed-off-by: David Bauer <mail@david-bauer.net>
diff --git a/target/linux/ipq40xx/base-files/etc/board.d/01_leds b/target/linux/ipq40xx/base-files/etc/board.d/01_leds
index 475a8623f705d683a7ee3521ee71f2b57fa2e44d..ab2f77ee10a8e4371d8c52d6d6b6a35bae8aceb6 100755
--- a/target/linux/ipq40xx/base-files/etc/board.d/01_leds
+++ b/target/linux/ipq40xx/base-files/etc/board.d/01_leds
@@ -35,9 +35,9 @@ meraki,mr33)
ucidef_set_interface_lan "eth0"
;;
zyxel,nbg6617)
- ucidef_set_led_wlan "wlan2g" "WLAN2G" "$board:green:wlan2G" "phy0tpt"
- ucidef_set_led_wlan "wlan5g" "WLAN5G" "$board:green:wlan5G" "phy1tpt"
- ucidef_set_led_usbport "usb" "USB" "${board}:green:usb" "usb1-port1" "usb2-port1" "usb3-port1" "usb4-port1"
+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "${boardname}:green:wlan2G" "phy0tpt"
+ ucidef_set_led_wlan "wlan5g" "WLAN5G" "${boardname}:green:wlan5G" "phy1tpt"
+ ucidef_set_led_usbport "usb" "USB" "${boardname}:green:usb" "usb1-port1" "usb2-port1" "usb3-port1" "usb4-port1"
;;
zyxel,wre6606)
ucidef_set_led_wlan "wlan2g" "WLAN2G" "${boardname}:green:wlan2g" "phy0tpt"
......@@ -43,6 +43,9 @@ packages $ATH10K_PACKAGES_IPQ40XX $ATH10K_PACKAGES_QCA9888
# ZyXEL
device zyxel-nbg6617 zyxel_nbg6617
packages $ATH10K_PACKAGES_IPQ40XX
device zyxel-wre6606 zyxel_wre6606
factory
packages $ATH10K_PACKAGES_IPQ40XX
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment