ipq40xx: add support for ZyXEL NBG6617 (#1560)
This commit is contained in:
		
							parent
							
								
									d3f2c5f87e
								
							
						
					
					
						commit
						a51ec56363
					
				| @ -315,6 +315,7 @@ ipq40xx | |||||||
| 
 | 
 | ||||||
| * ZyXEL | * ZyXEL | ||||||
| 
 | 
 | ||||||
|  |   - NBG6617 [#80211s]_ | ||||||
|   - WRE6606 [#80211s]_ |   - WRE6606 [#80211s]_ | ||||||
| 
 | 
 | ||||||
| ipq806x | ipq806x | ||||||
|  | |||||||
							
								
								
									
										1023
									
								
								patches/openwrt/0009-ipq40xx-add-support-for-the-ZyXEL-NBG6617.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1023
									
								
								patches/openwrt/0009-ipq40xx-add-support-for-the-ZyXEL-NBG6617.patch
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										782
									
								
								patches/openwrt/0010-build-add-mkrasimage.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										782
									
								
								patches/openwrt/0010-build-add-mkrasimage.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,782 @@ | |||||||
|  | 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();
 | ||||||
|  | +}
 | ||||||
							
								
								
									
										27
									
								
								patches/openwrt/0011-ipq40xx-fix-NBG6617-LED-mapping.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								patches/openwrt/0011-ipq40xx-fix-NBG6617-LED-mapping.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | 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 | # ZyXEL | ||||||
| 
 | 
 | ||||||
|  | device zyxel-nbg6617 zyxel_nbg6617 | ||||||
|  | packages $ATH10K_PACKAGES_IPQ40XX | ||||||
|  | 
 | ||||||
| device zyxel-wre6606 zyxel_wre6606 | device zyxel-wre6606 zyxel_wre6606 | ||||||
| factory | factory | ||||||
| packages $ATH10K_PACKAGES_IPQ40XX | packages $ATH10K_PACKAGES_IPQ40XX | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user