Add macros and a python script to build images compatible with tplink CFE bootloaders.
Signed-off-by: Daniel González Cabanelas <dgcb...@gmail.com> --- Changes in v2: - factory image fixed. (cfe-tplink-crcfix.py doesn't work if CFE already prepended) Changes in v3: - name in temp files for prepending CFE fixed to be safer. scripts/cfe-tplink-crcfix.py | 48 +++++++++++++++++++++++++++ target/linux/bcm63xx/image/Makefile | 23 +++++++++++++ target/linux/bcm63xx/image/bcm63xx.mk | 19 +++++++++++ 3 files changed, 90 insertions(+) create mode 100755 scripts/cfe-tplink-crcfix.py diff --git a/scripts/cfe-tplink-crcfix.py b/scripts/cfe-tplink-crcfix.py new file mode 100755 index 0000000000..2db6d6cce9 --- /dev/null +++ b/scripts/cfe-tplink-crcfix.py @@ -0,0 +1,48 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2022 OpenWrt.org, based on cameo-tag.py +# +# this tool fixes the CRC32 (kernel+rootfs) found in CFE headers from +# Tp-Link bcm63xx devices. It doesn't recalculate header checksums +# since CFE doesn't make any header integrity verification to boot OpenWrt. + +import argparse +import os +import struct +import zlib + +READ_UNTIL_EOF = -1 +CFE_HEADER_SIZE = 512 + +def read_buffer(offset, count): + args.cfeimage_file.seek(offset) + return bytearray(args.cfeimage_file.read(count)) + +def write_buffer(whence, buf): + args.cfeimage_file.seek(0, whence) + args.cfeimage_file.write(buf) + +def invertcrc(buf): + return (zlib.crc32(buf) ^ 0xffffffff).to_bytes(4, 'big') + +def checksum_header(buf): + BINCRC32 = args.crc_offset + ROOTFSADDRESS = buf[124:128] + ROOTFSLEN = buf[128:132] + IMLEN = struct.unpack('>i', ROOTFSADDRESS)[0] + struct.unpack('>i', ROOTFSLEN)[0] + CFE_HEADER_SIZE + buf[BINCRC32:BINCRC32+4] = invertcrc(buf[CFE_HEADER_SIZE:IMLEN]) + return buf + +parser = argparse.ArgumentParser(description='Insert CRC in tplink CFE firmware tags.') +parser.add_argument('cfeimage_file', type=argparse.FileType('r+b')) +# crc_offset should be 148 or 152 +parser.add_argument('crc_offset', type=int) +args = parser.parse_args() + +args.cfeimage_file.seek(0, os.SEEK_END) +if args.cfeimage_file.tell() <= CFE_HEADER_SIZE: + raise ValueError(f"CFE image must be larger than {CFE_HEADER_SIZE} bytes") + +buf = checksum_header(read_buffer(0, READ_UNTIL_EOF)) +write_buffer(os.SEEK_SET, buf) diff --git a/target/linux/bcm63xx/image/Makefile b/target/linux/bcm63xx/image/Makefile index f35358173c..019596e004 100644 --- a/target/linux/bcm63xx/image/Makefile +++ b/target/linux/bcm63xx/image/Makefile @@ -143,6 +143,15 @@ define Build/cfe-jffs2-cferam rm -f $@.kernel endef +define Build/cfe-kernel-header + $(TOPDIR)/scripts/cfe-bin-header.py \ + --input-file $@ \ + --output-file $@-tmp \ + --load-addr $(if $(DEVICE_LOADADDR),$(DEVICE_LOADADDR),$(LOADER_ENTRY)) \ + --entry-addr $(if $(DEVICE_LOADADDR),$(DEVICE_LOADADDR),$(LOADER_ENTRY)) + mv $@-tmp $@ +endef + define Build/cfe-jffs2-kernel rm -rf $@-kernel mkdir -p $@-kernel @@ -274,6 +283,20 @@ define Build/zyxel-bin mv $@.zyxel $@ endef +define Build/tplink-prepend-cfe + dd if=$(KDIR)/bcm63xx-cfe/$(CFE_BIN_FILE) bs=128k conv=sync of=$@.cfeprepend + dd if=$@ >> $@.cfeprepend + mv $@.cfeprepend $@ +endef + +define Build/tplink-sysupgrade + # append 512 bytes to avoid computing CRC for data beyond jffs2 EOF mark + dd if=/dev/null bs=512 count=1 >> $(IMAGE_ROOTFS) + $(call Build/tplink-v2-image, -v 0.9.1 -s) + # insert ~CRC32 (rootfs+kernel) to allow CFE booting Openwrt + $(TOPDIR)/scripts/cfe-tplink-crcfix.py $@ $(TPLINK_CRC_OFFSET) +endef + define Build/redboot-bin # Prepare kernel and rootfs dd if=$(IMAGE_KERNEL) of=$(BIN_DIR)/$(REDBOOT_PREFIX)-vmlinux.gz bs=65536 conv=sync diff --git a/target/linux/bcm63xx/image/bcm63xx.mk b/target/linux/bcm63xx/image/bcm63xx.mk index 97959d7819..bbf4da6505 100644 --- a/target/linux/bcm63xx/image/bcm63xx.mk +++ b/target/linux/bcm63xx/image/bcm63xx.mk @@ -5,9 +5,12 @@ DEVICE_VARS += HCS_MAGIC_BYTES HCS_REV_MIN HCS_REV_MAJ DEVICE_VARS += BLOCK_SIZE FLASH_MB IMAGE_OFFSET +DEVICE_VARS += CFE_BIN_FILE DEVICE_VARS += CFE_BOARD_ID CFE_EXTRAS DEVICE_VARS += NETGEAR_BOARD_ID NETGEAR_REGION DEVICE_VARS += REDBOOT_PREFIX +DEVICE_VARS += TPLINK_HWID TPLINK_HWREV TPLINK_FLASHLAYOUT +DEVICE_VARS += TPLINK_HWREVADD TPLINK_HVERSION TPLINK_CRC_OFFSET define Device/bcm33xx KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | loader-lzma bin | hcs-initramfs @@ -59,6 +62,22 @@ define Device/bcm63xx_redboot REDBOOT_PREFIX := $$(DEVICE_IMG_PREFIX) endef +define Device/bcm63xx_tplink + FILESYSTEMS := squashfs + DEVICE_VENDOR := TP-Link + TPLINK_HWID := 0x0 + TPLINK_HWREV := 0x1 + TPLINK_HWREVADD := 0x0 + TPLINK_HVERSION := 3 + TPLINK_FLASHLAYOUT := + TPLINK_CRC_OFFSET := 152 + CFE_BIN_FILE := + KERNEL := kernel-bin | append-dtb | relocate-kernel | lzma | cfe-kernel-header + IMAGES := factory.bin sysupgrade.bin + IMAGE/sysupgrade.bin := tplink-sysupgrade + IMAGE/factory.bin := tplink-sysupgrade | tplink-prepend-cfe +endef + ### Generic ### define Device/brcm_bcm963281tan $(Device/bcm63xx) -- 2.38.1 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel