From eea2581a6ab99f62ce12137cc69e317d8de67215 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 7 Aug 2024 15:52:58 +0800 Subject: [PATCH] add sonicfi rap630w 211g Signed-off-by: Your Name --- include/image-commands.mk | 27 ++ package/base-files/files/lib/upgrade/stage2 | 2 +- scripts/mkits_sonicfi_rap630w_211g.sh | 237 ++++++++++++++++ tools/Makefile | 1 + tools/crc32sum/Makefile | 23 ++ tools/crc32sum/src/Makefile | 18 ++ tools/crc32sum/src/crc32sum.c | 282 ++++++++++++++++++++ 7 files changed, 589 insertions(+), 1 deletion(-) create mode 100755 scripts/mkits_sonicfi_rap630w_211g.sh create mode 100644 tools/crc32sum/Makefile create mode 100644 tools/crc32sum/src/Makefile create mode 100644 tools/crc32sum/src/crc32sum.c diff --git a/include/image-commands.mk b/include/image-commands.mk index dc6ee6e7c1..0013eeb540 100644 --- a/include/image-commands.mk +++ b/include/image-commands.mk @@ -291,6 +291,32 @@ define Build/initrd_compression $(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_ZSTD),.zstd) endef +ifeq ($(CONFIG_TARGET_mediatek_mt7981_DEVICE_sonicfi_rap630w_211g),y) +define Build/fit + $(TOPDIR)/scripts/mkits_sonicfi_rap630w_211g.sh \ + -D $(DEVICE_NAME) -o $@.its -k $@ \ + -C $(word 1,$(1)) \ + $(if $(word 2,$(1)),\ + $(if $(findstring 11,$(if $(DEVICE_DTS_OVERLAY),1)$(if $(findstring $(KERNEL_BUILD_DIR)/image-,$(word 2,$(1))),,1)), \ + -d $(KERNEL_BUILD_DIR)/image-$$(basename $(word 2,$(1))), \ + -d $(word 2,$(1)))) \ + $(if $(findstring with-rootfs,$(word 3,$(1))),-r $(IMAGE_ROOTFS)) \ + $(if $(findstring with-initrd,$(word 3,$(1))), \ + $(if $(CONFIG_TARGET_ROOTFS_INITRAMFS_SEPARATE), \ + -i $(KERNEL_BUILD_DIR)/initrd.cpio$(strip $(call Build/initrd_compression)))) \ + -a $(KERNEL_LOADADDR) -e $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \ + $(if $(DEVICE_FDT_NUM),-n $(DEVICE_FDT_NUM)) \ + $(if $(DEVICE_DTS_DELIMITER),-l $(DEVICE_DTS_DELIMITER)) \ + $(if $(DEVICE_DTS_LOADADDR),-s $(DEVICE_DTS_LOADADDR)) \ + $(if $(DEVICE_DTS_OVERLAY),$(foreach dtso,$(DEVICE_DTS_OVERLAY), -O $(dtso):$(KERNEL_BUILD_DIR)/image-$(dtso).dtbo)) \ + -c $(if $(DEVICE_DTS_CONFIG),$(DEVICE_DTS_CONFIG),"config-1") \ + -A $(LINUX_KARCH) -v $(LINUX_VERSION) \ + $(if $(CONFIG_TARGET_ROOTFS_SQUASHFS),-r $(ROOTFS/squashfs/$(DEVICE_NAME))) + PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage $(if $(findstring external,$(word 3,$(1))),\ + -E -B 0x1000 $(if $(findstring static,$(word 3,$(1))),-p 0x1000)) -f $@.its $@.new + @mv $@.new $@ +endef +else define Build/fit $(TOPDIR)/scripts/mkits.sh \ -D $(DEVICE_NAME) -o $@.its -k $@ \ @@ -314,6 +340,7 @@ define Build/fit -E -B 0x1000 $(if $(findstring static,$(word 3,$(1))),-p 0x1000)) -f $@.its $@.new @mv $@.new $@ endef +endif define Build/libdeflate-gzip $(STAGING_DIR_HOST)/bin/libdeflate-gzip -f -12 -c $@ $(1) > $@.new diff --git a/package/base-files/files/lib/upgrade/stage2 b/package/base-files/files/lib/upgrade/stage2 index 5ce0b3549c..2f1cb45b6e 100755 --- a/package/base-files/files/lib/upgrade/stage2 +++ b/package/base-files/files/lib/upgrade/stage2 @@ -11,7 +11,7 @@ export VERBOSE=1 export CONFFILES=/tmp/sysupgrade.conffiles RAMFS_COPY_BIN= # extra programs for temporary ramfs root -RAMFS_COPY_DATA= # extra data files +RAMFS_COPY_DATA="/lib/upgrade/sonicfi/*.sh" # extra data files include /lib/upgrade diff --git a/scripts/mkits_sonicfi_rap630w_211g.sh b/scripts/mkits_sonicfi_rap630w_211g.sh new file mode 100755 index 0000000000..35f2d00767 --- /dev/null +++ b/scripts/mkits_sonicfi_rap630w_211g.sh @@ -0,0 +1,237 @@ +#!/bin/sh +# +# Licensed under the terms of the GNU GPL License version 2 or later. +# +# Author: Peter Tyser +# +# U-Boot firmware supports the booting of images in the Flattened Image +# Tree (FIT) format. The FIT format uses a device tree structure to +# describe a kernel image, device tree blob, ramdisk, etc. This script +# creates an Image Tree Source (.its file) which can be passed to the +# 'mkimage' utility to generate an Image Tree Blob (.itb file). The .itb +# file can then be booted by U-Boot (or other bootloaders which support +# FIT images). See doc/uImage.FIT/howto.txt in U-Boot source code for +# additional information on FIT images. +# + +usage() { + printf "Usage: %s -A arch -C comp -a addr -e entry" "$(basename "$0")" + printf " -v version -k kernel [-D name -n address -d dtb] -o its_file" + + printf "\n\t-A ==> set architecture to 'arch'" + printf "\n\t-C ==> set compression type 'comp'" + printf "\n\t-c ==> set config name 'config'" + printf "\n\t-a ==> set load address to 'addr' (hex)" + printf "\n\t-e ==> set entry point to 'entry' (hex)" + printf "\n\t-f ==> set device tree compatible string" + printf "\n\t-i ==> include initrd Blob 'initrd'" + printf "\n\t-v ==> set kernel version to 'version'" + printf "\n\t-k ==> include kernel image 'kernel'" + printf "\n\t-D ==> human friendly Device Tree Blob 'name'" + printf "\n\t-n ==> fdt unit-address 'address'" + printf "\n\t-d ==> include Device Tree Blob 'dtb'" + printf "\n\t-r ==> include RootFS blob 'rootfs'" + printf "\n\t-H ==> specify hash algo instead of SHA1" + printf "\n\t-l ==> legacy mode character (@ etc otherwise -)" + printf "\n\t-o ==> create output file 'its_file'" + printf "\n\t-O ==> create config with dt overlay 'name:dtb'" + printf "\n\t-s ==> set FDT load address to 'addr' (hex)" + printf "\n\t\t(can be specified more than once)\n" + exit 1 +} + +REFERENCE_CHAR='-' +FDTNUM=1 +ROOTFSNUM=1 +INITRDNUM=1 +HASH=sha1 +LOADABLES= +DTOVERLAY= +DTADDR= + +while getopts ":A:a:c:C:D:d:e:f:i:k:l:n:o:O:v:r:s:H:" OPTION +do + case $OPTION in + A ) ARCH=$OPTARG;; + a ) LOAD_ADDR=$OPTARG;; + c ) CONFIG=$OPTARG;; + C ) COMPRESS=$OPTARG;; + D ) DEVICE=$OPTARG;; + d ) DTB=$OPTARG;; + e ) ENTRY_ADDR=$OPTARG;; + f ) COMPATIBLE=$OPTARG;; + i ) INITRD=$OPTARG;; + k ) KERNEL=$OPTARG;; + l ) REFERENCE_CHAR=$OPTARG;; + n ) FDTNUM=$OPTARG;; + o ) OUTPUT=$OPTARG;; + O ) DTOVERLAY="$DTOVERLAY ${OPTARG}";; + r ) ROOTFS=$OPTARG;; + s ) FDTADDR=$OPTARG;; + H ) HASH=$OPTARG;; + v ) VERSION=$OPTARG;; + * ) echo "Invalid option passed to '$0' (options:$*)" + usage;; + esac +done + +# Make sure user entered all required parameters +if [ -z "${ARCH}" ] || [ -z "${COMPRESS}" ] || [ -z "${LOAD_ADDR}" ] || \ + [ -z "${ENTRY_ADDR}" ] || [ -z "${VERSION}" ] || [ -z "${KERNEL}" ] || \ + [ -z "${OUTPUT}" ] || [ -z "${CONFIG}" ]; then + usage +fi + +ARCH_UPPER=$(echo "$ARCH" | tr '[:lower:]' '[:upper:]') + +if [ -n "${COMPATIBLE}" ]; then + COMPATIBLE_PROP="compatible = \"${COMPATIBLE}\";" +fi + +[ "$FDTADDR" ] && { + DTADDR="$FDTADDR" +} + +# Conditionally create fdt information +if [ -n "${DTB}" ]; then + FDT_NODE=" + fdt${REFERENCE_CHAR}$FDTNUM { + description = \"${ARCH_UPPER} OpenWrt ${DEVICE} device tree blob\"; + ${COMPATIBLE_PROP} + data = /incbin/(\"${DTB}\"); + type = \"flat_dt\"; + ${DTADDR:+load = <${DTADDR}>;} + arch = \"${ARCH}\"; + compression = \"none\"; + hash${REFERENCE_CHAR}1 { + algo = \"crc32\"; + }; + hash${REFERENCE_CHAR}2 { + algo = \"${HASH}\"; + }; + }; +" + FDT_PROP="fdt = \"fdt${REFERENCE_CHAR}$FDTNUM\";" +fi + +if [ -n "${INITRD}" ]; then + INITRD_NODE=" + initrd${REFERENCE_CHAR}$INITRDNUM { + description = \"${ARCH_UPPER} OpenWrt ${DEVICE} initrd\"; + ${COMPATIBLE_PROP} + data = /incbin/(\"${INITRD}\"); + type = \"ramdisk\"; + arch = \"${ARCH}\"; + os = \"linux\"; + hash${REFERENCE_CHAR}1 { + algo = \"crc32\"; + }; + hash${REFERENCE_CHAR}2 { + algo = \"${HASH}\"; + }; + }; +" + INITRD_PROP="ramdisk=\"initrd${REFERENCE_CHAR}${INITRDNUM}\";" +fi + + +if [ -n "${ROOTFS}" ]; then + ROOTFS_SIZE=$(stat -c %s ${ROOTFS}) + ROOTFS_SHA1=$(sha1sum ${ROOTFS} | awk '{print "<0x"substr($0,1,8) " 0x"substr($0,9,8) " 0x"substr($0,17,8) " 0x"substr($0,25,8) " 0x"substr($0,33,8) ">"}') + ROOTFS_CRC32=$(crc32sum ${ROOTFS}) + ROOTFS_NODE=" + rootfs { + size = <${ROOTFS_SIZE}>; + hash-1 { + value = <0x${ROOTFS_CRC32}>; + algo = \"crc32\"; + }; + hash-2 { + value = ${ROOTFS_SHA1}; + algo = \"sha1\"; + }; + }; +" +fi + +# add DT overlay blobs +FDTOVERLAY_NODE="" +OVCONFIGS="" +[ "$DTOVERLAY" ] && for overlay in $DTOVERLAY ; do + overlay_blob=${overlay##*:} + ovname=${overlay%%:*} + ovnode="fdt-$ovname" + ovsize=$(wc -c "$overlay_blob" | awk '{print $1}') + echo "$ovname ($overlay_blob) : $ovsize" >&2 + FDTOVERLAY_NODE="$FDTOVERLAY_NODE + + $ovnode { + description = \"${ARCH_UPPER} OpenWrt ${DEVICE} device tree overlay $ovname\"; + ${COMPATIBLE_PROP} + data = /incbin/(\"${overlay_blob}\"); + type = \"flat_dt\"; + arch = \"${ARCH}\"; + compression = \"none\"; + hash${REFERENCE_CHAR}1 { + algo = \"crc32\"; + }; + hash${REFERENCE_CHAR}2 { + algo = \"${HASH}\"; + }; + }; +" + OVCONFIGS="$OVCONFIGS + + $ovname { + description = \"OpenWrt ${DEVICE} overlay $ovname\"; + fdt = \"$ovnode\"; + ${COMPATIBLE_PROP} + }; + " +done + +# Create a default, fully populated DTS file +DATA="/dts-v1/; + +/ { + description = \"${ARCH_UPPER} OpenWrt FIT (Flattened Image Tree)\"; + #address-cells = <1>; + + images { + kernel${REFERENCE_CHAR}1 { + description = \"${ARCH_UPPER} OpenWrt Linux-${VERSION}\"; + data = /incbin/(\"${KERNEL}\"); + type = \"kernel\"; + arch = \"${ARCH}\"; + os = \"linux\"; + compression = \"${COMPRESS}\"; + load = <${LOAD_ADDR}>; + entry = <${ENTRY_ADDR}>; + hash${REFERENCE_CHAR}1 { + algo = \"crc32\"; + }; + hash${REFERENCE_CHAR}2 { + algo = \"$HASH\"; + }; + }; +${INITRD_NODE} +${FDT_NODE} +${FDTOVERLAY_NODE} + }; +${ROOTFS_NODE} + configurations { + default = \"${CONFIG}\"; + ${CONFIG} { + description = \"OpenWrt ${DEVICE}\"; + kernel = \"kernel${REFERENCE_CHAR}1\"; + ${FDT_PROP} + ${LOADABLES:+loadables = ${LOADABLES};} + ${COMPATIBLE_PROP} + ${INITRD_PROP} + }; + ${OVCONFIGS} + }; +};" + +# Write .its file to disk +echo "$DATA" > "${OUTPUT}" diff --git a/tools/Makefile b/tools/Makefile index 40c3ec1ab0..6c7abaaf9c 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -68,6 +68,7 @@ tools-y += sstrip tools-y += zip tools-y += zlib tools-y += zstd +tools-y += crc32sum tools-$(if $(CONFIG_BUILD_ALL_HOST_TOOLS),y) += liblzo tools-$(if $(CONFIG_BUILD_ALL_HOST_TOOLS)$(BUILD_B43_TOOLS),y) += b43-tools tools-$(if $(CONFIG_BUILD_ALL_HOST_TOOLS)$(BUILD_BZIP2_TOOLS),y) += bzip2 diff --git a/tools/crc32sum/Makefile b/tools/crc32sum/Makefile new file mode 100644 index 0000000000..bc13ecf92b --- /dev/null +++ b/tools/crc32sum/Makefile @@ -0,0 +1,23 @@ +# +# Copyright (C) 2021 MediaTek Inc. All rights reserved. +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=crc32sum +PKG_VERSION:=1.0 + +include $(INCLUDE_DIR)/host-build.mk + +define Host/Prepare + mkdir -p $(HOST_BUILD_DIR) + $(CP) -a ./src/* $(HOST_BUILD_DIR)/ +endef + +define Host/Install + $(INSTALL_BIN) $(HOST_BUILD_DIR)/crc32sum $(STAGING_DIR_HOST)/bin/ +endef + +$(eval $(call HostBuild)) diff --git a/tools/crc32sum/src/Makefile b/tools/crc32sum/src/Makefile new file mode 100644 index 0000000000..7428ba2f54 --- /dev/null +++ b/tools/crc32sum/src/Makefile @@ -0,0 +1,18 @@ +# +# Copyright (C) 2021 MediaTek Inc. All rights reserved. +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +all: crc32sum + +crc32sum: crc32sum.c + $(CC) $(CFLAGS) -O2 -ggdb -MD -o $@ $< $(LDFLAGS) + +clean: + rm -f crc32sum crc32sum.d + +.PHONY: clean + +-include crc32sum.d diff --git a/tools/crc32sum/src/crc32sum.c b/tools/crc32sum/src/crc32sum.c new file mode 100644 index 0000000000..381c7a95a7 --- /dev/null +++ b/tools/crc32sum/src/crc32sum.c @@ -0,0 +1,282 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#include +#define SET_BINARY_MODE(_f) _setmode(_fileno(_f, O_BINARY) +#else +#define SET_BINARY_MODE(_f) ((void)0) +#endif + +#define CRC32_LE_POLY_DEFAULT 0xedb88320 +#define CRC32_BE_POLY_DEFAULT 0x04c11db7 +#define CRC32_TABLE_ITEMS 256 + +static uint32_t crc32_le_calc(uint32_t crc, const uint8_t *data, size_t length, + const uint32_t *crc_table) +{ + while (length--) + crc = crc_table[(uint8_t)(crc ^ *data++)] ^ (crc >> 8); + + return crc; +} + +static void crc32_le_init(uint32_t *crc_table, uint32_t poly) +{ + uint32_t i, j, v; + + for (i = 0; i < CRC32_TABLE_ITEMS; i++) { + v = i; + + for (j = 0; j < 8; j++) + v = (v >> 1) ^ ((v & 1) ? poly : 0); + + crc_table[i] = v; + } +} + +static uint32_t crc32_be_calc(uint32_t crc, const uint8_t *data, size_t length, + const uint32_t *crc_table) +{ + while (length--) + crc = crc_table[(uint8_t)((crc >> 24) ^ *data++)] ^ (crc << 8); + + return crc; +} + +static void crc32_be_init(uint32_t *crc_table, uint32_t poly) +{ + uint32_t i, j, v; + + for (i = 0; i < CRC32_TABLE_ITEMS; i++) { + v = i << 24; + + for (j = 0; j < 8; j++) + v = (v << 1) ^ ((v & (1 << 31)) ? poly : 0); + + crc_table[i] = v; + } +} + +struct crc_funcs { + uint32_t poly; + + void (*init)(uint32_t *crc_table, uint32_t poly); + uint32_t (*calc)(uint32_t crc, const uint8_t *data, size_t length, + const uint32_t *crc_table); +}; + +static const struct crc_funcs crc32_le = { + .poly = CRC32_LE_POLY_DEFAULT, + .init = crc32_le_init, + .calc = crc32_le_calc, +}; + +static const struct crc_funcs crc32_be = { + .poly = CRC32_BE_POLY_DEFAULT, + .init = crc32_be_init, + .calc = crc32_be_calc, +}; + +static const struct crc_funcs *crc32_algo = &crc32_le; +static uint32_t crc32_poly; +static uint32_t crc32_val; +static const char *input_file; +static bool output_decimal; +static bool no_comp; + +static void err(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fprintf(stderr, "Error: "); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +static void usage(FILE *con, const char *progname, int exitcode) +{ + const char *prog; + size_t len; + + len = strlen(progname); + prog = progname + len - 1; + + while (prog > progname) { + if (*prog == '\\' || *prog == '/') { + prog++; + break; + } + + prog--; + } + + fprintf(con, "CRC32 checksum tool\n"); + fprintf(con, "\n"); + fprintf(con, "Usage: %s [options] \n", prog); + fprintf(con, "\n"); + fprintf(con, "Options:\n"); + fprintf(con, "\t-h display help message\n"); + fprintf(con, "\t-i crc value for incremental calculation\n"); + fprintf(con, "\t (default is 0)\n"); + fprintf(con, "\t-p polynomial for calculation\n"); + fprintf(con, "\t (default is 0x%08x for LE, 0x%08x for BE)\n", + crc32_le.poly, crc32_be.poly); + fprintf(con, "\t-b use big-endian mode\n"); + fprintf(con, "\t-n do not use one's complement\n"); + fprintf(con, "\t-d use decimal output\n"); + fprintf(con, "\n"); + + exit(exitcode); +} + +static int parse_args(int argc, char *argv[]) +{ + int opt; + + static const char *optstring = "i:p:bndh"; + + opterr = 0; + + while ((opt = getopt(argc, argv, optstring)) >= 0) { + switch (opt) { + case 'i': + if (!isxdigit(optarg[0])) { + err("Invalid crc value - %s\n", optarg); + return -EINVAL; + } + + crc32_val = strtoul(optarg, NULL, 0); + break; + + case 'p': + if (!isxdigit(optarg[0])) { + err("Invalid polynomial value - %s\n", optarg); + return -EINVAL; + } + + crc32_poly = strtoul(optarg, NULL, 0); + break; + + case 'b': + crc32_algo = &crc32_be; + break; + + case 'n': + no_comp = true; + break; + + case 'd': + output_decimal = true; + break; + + case 'h': + usage(stdout, argv[0], 0); + break; + + default: + usage(stderr, argv[0], EXIT_FAILURE); + } + } + + if (!crc32_poly) + crc32_poly = crc32_algo->poly; + + if (optind >= argc) + input_file = "-"; + else + input_file = argv[optind]; + + if (!input_file[0]) { + err("Input file must not be empty\n"); + return -EINVAL; + } + + return 0; +} + +static int crc32_calc(void) +{ + uint32_t crc_table[CRC32_TABLE_ITEMS]; + bool using_stdin = false; + uint8_t buf[4096]; + size_t size; + int ret, i; + FILE *f; + + if (!strcmp(input_file, "-")) { + SET_BINARY_MODE(stdin); + using_stdin = true; + f = stdin; + } else { + f = fopen(input_file, "rb"); + } + + if (!f) { + err("Failed to open file '%s'\n", input_file); + return -EINVAL; + } + + crc32_algo->init(crc_table, crc32_poly); + + if (!no_comp) + crc32_val ^= 0xffffffff; + + do { + size = fread(buf, 1, sizeof(buf), f); + + if (size) { + crc32_val = crc32_algo->calc(crc32_val, buf, size, + crc_table); + } + + if (size < sizeof(buf)) { + ret = ferror(f); + + if (!ret && feof(f)) + break; + + err("Error while reading file: %d\n", ret); + break; + } + } while (true); + + if (!using_stdin) + fclose(f); + + if (ret) + return ret; + + if (!no_comp) + crc32_val ^= 0xffffffff; + + if (output_decimal) + printf("%u\n", crc32_val); + else + printf("%08x\n", crc32_val); + + return 0; +} + +int main(int argc, char *argv[]) +{ + if (parse_args(argc, argv)) + return 1; + + return crc32_calc(); +} -- 2.43.2