image: fix Linksys image alignment and simplify footer creation
authorTony Ambardar <itugrok@yahoo.com>
Tue, 14 Nov 2023 01:14:07 +0000 (17:14 -0800)
committerHauke Mehrtens <hauke@hauke-m.de>
Sun, 26 Nov 2023 17:37:20 +0000 (18:37 +0100)
Current factory image sizes for Linksys devices are 256-byte aligned. This
is not an issue writing factory images from the OpenWrt or Linksys GUIs,
but can lead to failures using a TFTP client from the Linksys bootloader:

     NAND write: device 1 offset 0x2800000, size 0xc00100
     Attempt to write to non page aligned data
     NAND write to offset 2800000 failed -22
      0 bytes written: ERROR

Simplify Linksys footer creation by migrating to a makefile build recipe,
and pre-pad the footer (with 0xFF) to ensure the final image is $(PAGESIZE)
aligned.  Finally, remove the old linksys-image.sh script no longer needed.

Linksys footer details are given below for future reference. The 256-byte
footer is appended to factory images and tested by both the Linksys
Upgrader (observed in EA6350v3) and OpenWrt sysupgrade.

  Footer format:
    .LINKSYS.     Checked by Linksys upgrader before continuing.  (9 bytes)
    <VERSION>     Upgrade version number, unchecked so arbitrary. (8 bytes)
    <TYPE>        Model of device, space padded (0x20).          (15 bytes)
    <CRC>         CRC checksum of factory image to flash.         (8 bytes)
    <padding>     Padding ('0' + 0x20 * 7)                        (8 bytes)
    <signature>   Signature of signer, unchecked so arbitrary.   (16 bytes)
    <padding>     Padding with nulls (0x00)                     (192 bytes)

Link: https://github.com/openwrt/openwrt/pull/11405#issuecomment-1358510123
Link: https://github.com/openwrt/openwrt/pull/11405#issuecomment-1587517739
Reported-by: Stijn Segers <foss@volatilesystems.org>
Reported-by: Wyatt Martin <wawowl@gmail.com>
Signed-off-by: Tony Ambardar <itugrok@yahoo.com>
include/image-commands.mk
scripts/linksys-image.sh [deleted file]

index 0f292d15ee364a173a6ef79a5021af22aebfbbb0..7d9f93fed741053d72574cc02124d849ab65c4b3 100644 (file)
@@ -389,10 +389,17 @@ define Build/kernel-bin
 endef
 
 define Build/linksys-image
-       $(TOPDIR)/scripts/linksys-image.sh \
+       let \
+               size="$$(stat -c%s $@)" \
+               pad="$(call exp_units,$(PAGESIZE))" \
+               offset="256" \
+               pad="(pad - ((size + offset) % pad)) % pad"; \
+               dd if=/dev/zero bs=$$pad count=1 | tr '\000' '\377' >> $@
+       printf ".LINKSYS.01000409%-15s%08X%-8s%-16s" \
                "$(call param_get_default,type,$(1),$(DEVICE_NAME))" \
-               $@ $@.new
-               mv $@.new $@
+               "$$(cksum $@ | cut -d ' ' -f1)" \
+               "0" "K0000000F0246434" >> $@
+       dd if=/dev/zero bs=192 count=1 >> $@
 endef
 
 define Build/lzma
diff --git a/scripts/linksys-image.sh b/scripts/linksys-image.sh
deleted file mode 100755 (executable)
index d251b5d..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/bin/sh
-#
-# Copyright (C) 2018 Oceanic Systems (UK) Ltd
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-# Maintained by: Ryan Pannell <ryan [at] o s u k l .com> <github.com/Escalion>
-#
-# Write Linksys signature for factory image
-# This is appended to the factory image and is tested by the Linksys Upgrader - as observed in civic.
-# The footer is 256 bytes. The format is:
-#  .LINKSYS.        This is detected by the Linksys upgrader before continuing with upgrade. (9 bytes)
-#  <VERSION>        The version number of upgrade. Not checked so use arbitrary value (8 bytes)
-#  <TYPE>           Model of target device, padded (0x20) to (15 bytes)
-#  <CRC>           CRC checksum of the image to flash (8 byte)
-#  <padding>       Padding ('0' + 0x20 *7) (8 bytes)
-#  <signature>     Signature of signer. Not checked so use arbitrary value (16 bytes)
-#  <padding>        Padding (0x00) (192 bytes)
-
-## version history
-# * version 1: initial commit
-
-set -e
-
-ME="${0##*/}"
-
-usage() {
-       echo "Usage: $ME <type> <in filename>"
-       [ "$IMG_OUT" ] && rm -f "$IMG_OUT"
-       exit 1
-}
-
-[ "$#" -lt 3 ] && usage
-
-TYPE=$1
-
-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
-
-trap "rm -rf $tmpdir" EXIT
-
-IMG_TMP_OUT="${tmpdir}/out"
-
-IMG_IN=$2
-IMG_OUT="${IMG_IN}.new"
-
-[ ! -f "$IMG_IN" ] && echo "$ME: Not a valid image: $IMG_IN" && usage
-
-dd if="${IMG_IN}" of="${IMG_TMP_OUT}"
-CRC=$(printf "%08X" $(dd if="${IMG_IN}" bs=$(stat -c%s "${IMG_IN}") count=1|cksum| cut -d ' ' -f1))
-
-printf ".LINKSYS.01000409%-15s%-8s%-8s%-16s" "${TYPE}" "${CRC}" "0" "K0000000F0246434" >> "${IMG_TMP_OUT}"
-
-dd if=/dev/zero bs=1 count=192 conv=notrunc >> "${IMG_TMP_OUT}"
-
-cp "${IMG_TMP_OUT}" "${IMG_OUT}"