#!/bin/bash # Freetz script to modify AVM FRITZ!Box and OEM firmware images # # Copyright (C) 2005-2006 Daniel Eiband # Copyright (C) 2006-2012 by the Freetz developers (http://freetz.org) # # Licensed under the GPL v2, see the file COPYING in this tarball. # # This script is based on Christian Volkmann's fritzbox mod-0.57. # Legacy URL: http://www.ip-phone-forum.de/showthread.php?t=65894 # # Special thanks to Andreas Buehmann, Christian Volkmann, Enrik Berkhan, # SpeedyBZ and all members on ip-phone-forum.de who contributed to this mod. usage() { cat << EOF Usage: $SELF [-u|-m|-p|-a] [-i ] [-d ] [] actions -u unpack firmware image -m modify previously unpacked image -p pack firmware image -a all: unpack, modify and pack firmware image (-u -m -p, default) special actions -n firmware-nocompile: do not install kernel and busybox -f force pack even if image is too big for flash (AVM SDK) -z zip file system into archive for USB/NFS root -c copy file system to target directory for NFS/USB root (implies -z) input/output -i input file for configuration data (default: .config) -d build directory (default: .mod) original firmware name 2nd firmware name (e.g. for merging in web UI) EOF } ################################################## ## Initialise and check command line parameters ## ################################################## # This script's name ("fwmod" if not linked/renamed) SELF="$(basename "$0")" # No parameters -> print usage info to stdout [ $# -eq 0 ] && usage && exit 0 # Backup command line parameters [$0..$n] to save them from getopts eating them # away, because we need them again later for the recursive fakerooted call. for ((i=0; i<=$#; i++)); do CMDLINE_ORIG[i]="${!i}" done # Default values for unset command line parameters DOT_CONFIG="$(dirname "$0")/.config" DO_UNPACK=0; DO_MOD=0; DO_PACK=0; FORCE_PACK=0; DO_ZIP=0; _OPT=0 COPY_FS_DIR=; DIR= # Parse command line parameters while getopts umpanfzc:i:d: opt; do case "$opt" in u) DO_UNPACK=1; _OPT=1 ;; m) DO_MOD=1; _OPT=1 ;; p) DO_PACK=1; _OPT=1 ;; a) DO_UNPACK=1; DO_MOD=1; DO_PACK=1; _OPT=1 ;; n) FIRMWARE_NOCOMPILE=1 ;; f) FORCE_PACK=1 ;; z) DO_ZIP=1 ;; c) COPY_FS_DIR="$OPTARG"; [ "$COPY_FS_DIR" ] && DO_ZIP=1 ;; i) DOT_CONFIG="$OPTARG" ;; d) DIR="$OPTARG" ;; *) usage >&2; exit 1 ;; esac done shift $((OPTIND-1)) # At least one (non-empty) firmware image name must be specified [ $# -ne 1 -a $# -ne 2 -o ! "$1" ] && usage >&2 && exit 1 # Freetz base + tools directories BASE_DIR="$(dirname "$0")" ABS_BASE_DIR="$(readlink -f "$BASE_DIR")" TOOLS_DIR="${ABS_BASE_DIR}/tools" # Include common helper functions (isFreetzType, echo*, error, modunsqfs* etc.) . "${TOOLS_DIR}/freetz_functions" || (echo "cannot find script freetz_functions" >&2; exit 1) # Initialise firmware image names FIRMWARE="$1" FIRMWARE2="$2" FIRMWARE_EXTENSION="${FIRMWARE##*.}" FIRMWARE_EXTENSION="${FIRMWARE_EXTENSION,,}" # Given firmware image(s) must exist [ -r "$FIRMWARE" ] || error 1 "firmware image $(basename "$FIRMWARE") not found" [ "$FIRMWARE2" -a ! -r "$FIRMWARE2" ] && error 1 "firmware image $(basename "$FIRMWARE2") not found" # Config file must exist [ -r "$DOT_CONFIG" ] || error 1 "not configured" # No -u/-m/-p/-a options = default = -a = -ump [ "$_OPT" -eq 0 ] && DO_UNPACK=1 && DO_MOD=1 && DO_PACK=1 # Set default output directory, if not specified on command line : ${DIR:=$FIRMWARE.mod} # Create output directory if necessary mkdir -p "$DIR" ################################# ## Initialise script variables ## ################################# # Relative subdirectories SOURCE_SUBDIR="source" FIRMWARE_SUBDIR="firmware" FILESYSTEM_SUBDIR="filesystem" FILESYSTEM_CORE_SUBDIR="filesystem_core" AVMPLUGINS_SUBDIR="plugins.image" EXTERNAL_SUBDIR="external" KERNEL_SUBDIR="kernel" VARTAR_SUBDIR="var.tar" HTML_SUBDIR="usr/www" GRAPHICS_SUBDIR="graphics" # Kernel/SquashFS images contained in firmware KERNEL_IMAGE="var/tmp/kernel.image" FILESYSTEM_IMAGE="var/tmp/filesystem.image" FILESYSTEM_CORE_IMAGE="filesystem_core.squashfs" # More files created during firmware unpacking AVMPLUGINS_FILE="var/tmp/plugins.update" RAW_KERNEL_FILE="kernel.raw" RAW_HIDDEN_FILE="kernelsquashfs.raw" VARTAR_FILE="var.tar" UNPACKED_FILE="$DIR/.unpacked" # Path to bash (shell required by fwmod) SHELL=$BASH # Tools used by fwmod FINDSQUASHFS_TOOL="find-squashfs" TICHKSUM_TOOL="tichksum" RMTICHKSUM_TOOL="rmtichksum" MAKEDEVS_TOOL="makedevs" UNSQUASHFS_TOOL="unsquashfs3" UNSQUASHFS_LZMA_TOOL="unsquashfs3-lzma" EXTERNAL_TOOL="external" TAR_TOOL="tar" MD5SUM_TOOL="md5sum" BUSYBOX_TOOL="busybox" # Options for (un)packing SquashFS MKSQUASHFS_OPTIONS="-noappend -all-root -info" UNSQUASHFS_OPTIONS="-no-progress" # Absolute tools paths EXTERNAL="${TOOLS_DIR}/${EXTERNAL_TOOL}" UNSQUASHFS="${TOOLS_DIR}/${UNSQUASHFS_TOOL}" UNSQUASHFS_LZMA="${TOOLS_DIR}/${UNSQUASHFS_LZMA_TOOL}" FINDSQUASHFS="${TOOLS_DIR}/${FINDSQUASHFS_TOOL}" MKSQUASHFS="${TOOLS_DIR}/${MKSQUASHFS_TOOL}" MKSQUASHFS_LZMA="${TOOLS_DIR}/${MKSQUASHFS_LZMA_TOOL}" TICHKSUM="${TOOLS_DIR}/${TICHKSUM_TOOL}" RMTICHKSUM="${TOOLS_DIR}/${RMTICHKSUM_TOOL}" MAKEDEVS="${TOOLS_DIR}/${MAKEDEVS_TOOL}" MAKEDEVS_FILE="${TOOLS_DIR}/device_table.txt" TAR="${TOOLS_DIR}/${TAR_TOOL}" MD5SUM="${TOOLS_DIR}/${MD5SUM_TOOL}" BUSYBOX="${TOOLS_DIR}/${BUSYBOX_TOOL}" # Temporarily use system's tar to unpack AVM firmware-images (see #1535) UNTAR="$(which tar)" # Freetz directores relative to base dir PACKAGES_DIR_ROOT="${BASE_DIR}/packages" PATCHES_DIR="${BASE_DIR}/patches" PATCHES_COND_DIR="${PATCHES_DIR}/cond" PATCHES_DEVICES_DIR="${PATCHES_DIR}/devices" PATCHES_SCRIPTS_DIR="${PATCHES_DIR}/scripts" ROOT_DIR="${BASE_DIR}/root" KERNEL_REP_DIR="${BASE_DIR}/kernel" ADDON_DIR="${BASE_DIR}/addon" GRAPHICS_DIR="${BASE_DIR}/${GRAPHICS_SUBDIR}" # Freetz branding directories relative to graphics subdirectory FAVICON_DIR="${GRAPHICS_DIR}/favicon" TAGGING_DIR="${GRAPHICS_DIR}/tagging" # Package files STATIC_PACKAGES_FILE="${BASE_DIR}/.static" DYNAMIC_PACKAGES_FILE="${BASE_DIR}/.dynamic" STATIC_ADDON_FILE="${ADDON_DIR}/static.pkg" DYNAMIC_ADDON_FILE="${ADDON_DIR}/dynamic.pkg" # Alien variables TK_DIR="${DIR}/.tk/original" FIRMWARE_TK_DIR="${TK_DIR}/${FIRMWARE_SUBDIR}" FILESYSTEM_TK_DIR="${TK_DIR}/${FILESYSTEM_SUBDIR}" KERNEL_TK_DIR="${TK_DIR}/${KERNEL_SUBDIR}" VARTAR_TK_DIR="${KERNEL_TK_DIR}/${VARTAR_SUBDIR}" ########################################################## ## Include config file + initialise some more variables ## ########################################################## # Include config file, but do not override variables which are already defined # in the environment, e.g. via "make FREETZ_SOMETHING=y" sed -nr 's/^([^=]+)=(.*)/: ${\1:=\2}/p' "$DOT_CONFIG" > "$DOT_CONFIG.fwmod" . "$DOT_CONFIG.fwmod" rm "$DOT_CONFIG.fwmod" # Set default verbosity level, just in case none was defined in the (possibly # user-defined and minimal) config file : ${FREETZ_VERBOSITY_LEVEL:=0} # If FREETZ_FWMOD_* options have been defined via config file or command line, # they overrule(!) normal command line options -u, -m, -p, -a, -f, -z, -c. [ "$FREETZ_FWMOD_SKIP_UNPACK" == "y" ] && DO_UNPACK=0 [ "$FREETZ_FWMOD_SKIP_MODIFY" == "y" ] && DO_MOD=0 [ "$FREETZ_FWMOD_SKIP_PACK" == "y" ] && DO_PACK=0 [ "$FREETZ_FWMOD_USBROOT" == "y" ] && DO_ZIP=1 [ "$FREETZ_FWMOD_SDK" == "y" ] && FORCE_PACK=1 [ "$FREETZ_FWMOD_NFSROOT_DIR" ] && COPY_FS_DIR="$FREETZ_FWMOD_NFSROOT_DIR" && DO_ZIP=1 # Use FREETZ_TARGET_CROSS to determine build tool paths NM="${ABS_BASE_DIR}/toolchain/target/bin/${FREETZ_TARGET_CROSS}nm" STRIP="${ABS_BASE_DIR}/toolchain/target/bin/${FREETZ_TARGET_CROSS}strip" # Use FREETZ_MODULES_KVER to determine MODULES_SUBDIR (see kernel/Config.in for details) MODULES_SUBDIR="lib/modules/${FREETZ_MODULES_KVER}" # Use FREETZ_TARGET_ARCH_BE to determine SquashFS endianness if [ "$FREETZ_TARGET_ARCH_BE" == "y" ]; then MKSQUASHFS_OPTIONS+=" -be" else MKSQUASHFS_OPTIONS+=" -le" fi # Use FREETZ_HAS_UPDATE_FILESYSTEM_IMAGE etc. to determine correct mksquashfs tool # TODO: Add new symbols for SquashFS version and LZMA compression to Config.in if [ "${FREETZ_HAS_UPDATE_FILESYSTEM_IMAGE}" == "y" ]; then MKSQUASHFS_TOOL="mksquashfs3" MKSQUASHFS_OPTIONS+=" -no-progress -no-exports -no-sparse" elif [ "$FREETZ_KERNEL_VERSION_2_6_13" -a ! "$FREETZ_REPLACE_KERNEL" == "y" ]; then MKSQUASHFS_TOOL="mksquashfs-lzma" else MKSQUASHFS_TOOL="mksquashfs3-lzma" MKSQUASHFS_OPTIONS+=" -no-progress -no-exports -no-sparse" fi ####################################### ## Initialise fakeroot incl. caching ## ####################################### # Create id string based on MD5 hashes of firmware images if [ "$FIRMWARE2" ]; then FIRMWARE_MD5="$("$MD5SUM" "$FIRMWARE2" | cut -d ' ' -f 1)" fi FIRMWARE_MD5="$("$MD5SUM" "$FIRMWARE" | cut -d ' ' -f 1)_$FIRMWARE_MD5" FAKEROOT="$TOOLS_DIR/build/bin/fakeroot" FAKEROOT_CACHE_DIR="$ABS_BASE_DIR/.fakeroot-cache" FAKEROOT_CACHE="$FAKEROOT_CACHE_DIR/$FIRMWARE_MD5" if [ ! -e "$FAKEROOT_CACHE_DIR" ]; then mkdir -p "$FAKEROOT_CACHE_DIR" fi # Are we in a fakeroot context? if [ "$FAKEROOTKEY" ] && [ $UID -eq 0 ]; then # Yes -> fakeroot is active # Make sure fakeroot call came from ourselves so we can assume the cache settings to be correct if [ $((FWMOD_RECURSIVE)) -eq 0 ] || [ "$SELF" != "$(sed -nr 's/^Name:[[:blank:]]+(.*)/\1/p' /proc/$FWMOD_RECURSIVE/status)" ]; then error 1 "$SELF must not run in a fakeroot environment" fi # Does fakeroot cache (size>0) exist for current combination of firmwares and has this combination already been unpacked? if [ -s "$FAKEROOT_CACHE" ] && [ -s "$UNPACKED_FILE" ] && [ "$(cat "$UNPACKED_FILE")" == "$FIRMWARE_MD5" ]; then # Yes -> skip unpack [ $DO_UNPACK -gt 0 ] && SKIP_UNPACK="STEP 1: UNPACK (SKIPPED)\n\n" DO_UNPACK=0 else # No -> force unpack [ $DO_UNPACK -eq 0 ] && FORCE_UNPACK=" (FORCED)" DO_UNPACK=1 fi else # No -> fakeroot is inactive # Does fakeroot cache (size>0) exist for current combination of firmwares and has this combination already been unpacked? if [ -s "$FAKEROOT_CACHE" ] && [ -s "$UNPACKED_FILE" ] && [ "$(cat "$UNPACKED_FILE")" == "$FIRMWARE_MD5" ]; then # Yes -> use existing cache and firmwares (no unpack necessary) FWMOD_RECURSIVE=$$ "$FAKEROOT" -i "$FAKEROOT_CACHE" -s "$FAKEROOT_CACHE" '--' "${CMDLINE_ORIG[@]}" else # No -> create new fakeroot cache and unpack firmwares FWMOD_RECURSIVE=$$ "$FAKEROOT" -s "$FAKEROOT_CACHE" '--' "${CMDLINE_ORIG[@]}" fi retval=$? [ $retval -eq 0 ] || exit $retval # ------------------------------------------------------------------ # -- Copy file system to target folder (NFS root, maybe USB root) -- # ------------------------------------------------------------------ # This cannot be done in the pack/zip section (needs real sudo, not fakeroot) if [ "$COPY_FS_DIR" ]; then echo0 "copying root file system to directory $COPY_FS_DIR" rootfs_archive="$(cat "${DIR}/.rootfs_archive")" || error 1 "cannot determine root file system archive name" [ -d "$COPY_FS_DIR" ] && (sudo rm -rf "$COPY_FS_DIR"/* || error 1 "cannot clean up directory $COPY_FS_DIR") mkdir -p "$COPY_FS_DIR" || error 1 "cannot create directory $COPY_FS_DIR" sudo "$TAR" -C "$COPY_FS_DIR" -xf "$rootfs_archive" || error 1 "cannot unpack root file system" echo -e "done.\n" echo0 -b "FINISHED" fi exit 0 fi ############################################ ## Unpack and unsquash the firmware image ## ############################################ ORG_DIR="${DIR}/original" FIRMWARE_DIR="${ORG_DIR}/${FIRMWARE_SUBDIR}" FILESYSTEM_DIR="${ORG_DIR}/${FILESYSTEM_SUBDIR}" FILESYSTEM_CORE_DIR="${ORG_DIR}/${FILESYSTEM_CORE_SUBDIR}" KERNEL_DIR="${ORG_DIR}/${KERNEL_SUBDIR}" AVMPLUGINS_DIR="${KERNEL_DIR}/${AVMPLUGINS_SUBDIR}" VARTAR_DIR="${KERNEL_DIR}/${VARTAR_SUBDIR}" HTML_DIR="${FILESYSTEM_DIR}/${HTML_SUBDIR}" RAW_KERNEL="${KERNEL_DIR}/${RAW_KERNEL_FILE}" RAW_FILESYSTEM="${KERNEL_DIR}/${RAW_HIDDEN_FILE}" KERNEL="${FIRMWARE_DIR}/${KERNEL_IMAGE}" if [ "${FREETZ_HAS_UPDATE_FILESYSTEM_IMAGE}" == "y" ]; then FILESYSTEM="$FILESYSTEM_CORE_DIR/$FILESYSTEM_CORE_IMAGE" else FILESYSTEM="${RAW_FILESYSTEM}" fi AVMPLUGINS="${FIRMWARE_DIR}/${AVMPLUGINS_FILE}" VARTAR="${FILESYSTEM_DIR}/${VARTAR_FILE}" if [ "$DO_UNPACK" -gt 0 ]; then [ "$FIRMWARE2" ] && UNPACK_SUBSTEP="A" && UNPACK_MAIN=" MAIN" echo0 -b "STEP 1${UNPACK_SUBSTEP}: UNPACK${UNPACK_MAIN}${FORCE_UNPACK}" # Remove old "unpacked" marker to avoid an undefined state in case of # interruption before unpacking operation is finished rm -f "$UNPACKED_FILE" rm -rf "$ORG_DIR" mkdir "$ORG_DIR" echo "unpacking firmware image" mkdir "$FIRMWARE_DIR" if [ "$FIRMWARE_EXTENSION" != "exe" ]; then # Check and skip garbage image_size="0x$(printf "%08X\n" $(stat -c %s "$FIRMWARE")) " image_grbg="$($TOOLS_DIR/sfk hexfind "$FIRMWARE" _./var/_ | sed -n 's/.*hit at offset //p' |head -n1)" [ "$grbg" != "0x0" ] && printf "Skipping %d Bytes garbage..." $grbg # Unpack standard *.image file in tar format tail -c $(( $image_size - $image_grbg )) "$FIRMWARE" | \ "$UNTAR" -xf "$FIRMWARE" -C "$FIRMWARE_DIR" || untar_failed=1 fi if [ "$FIRMWARE_EXTENSION" == "exe" ] || [ "$untar_failed" ]; then # Unpack Windows recover.exe file or mtdblock dump exe_images=($("${TOOLS_DIR}/extract-images" "$ABS_BASE_DIR" "$FIRMWARE" | sed -nr 's/^ *(.*\.image) - .*/\1/p')) [ "$exe_images" ] || exit 1 mkdir -p "$FIRMWARE_DIR/var/tmp" mkdir "$KERNEL_DIR" unset exe_hr_mode # NOTE: This loop is sensitive to the order and format of output of # "tools/extract-images", e.g. a hidden root image is always listed # before its parts. for (( i=0; i<${#exe_images[@]}; i++ )); do exe_image="${exe_images[i]}" case "$exe_image" in */urlader.image) mv "$exe_image" "$FIRMWARE_DIR/var/tmp" ;; */hr_kernel.image) exe_hr_mode=1 mv "$exe_image" "$FIRMWARE_DIR/var/tmp/kernel.image" touch "$FIRMWARE_DIR/var/tmp/filesystem.image" ;; */kernel.image) [ "$exe_hr_mode" ] || cp "$exe_image" "$FIRMWARE_DIR/var/tmp/kernel.image" mv "$exe_image" "$KERNEL_DIR/kernel.raw" ;; */filesystem.image) if [ "$exe_hr_mode" ]; then mv "$exe_image" "$KERNEL_DIR/kernelsquashfs.raw" else mv "$exe_image" "$FIRMWARE_DIR/var/tmp/filesystem.image" fi ;; esac done rm -r "$(dirname "$exe_image")" fi # Do the images exist ? [ ! -r "${KERNEL}" ] && error 1 "cannot find kernel.image" [ ! -r "${FIRMWARE_DIR}/${FILESYSTEM_IMAGE}" ] && error 1 "cannot find filesystem.image" # Do we have the tool ? for tool in "$RMTICHKSUM" "$UNSQUASHFS" "$FINDSQUASHFS"; do [ ! -x $tool ] && error 1 "cannot find the tool $tool" done # Remove AVM's special junk bytes from SquashFS if [ "$FREETZ_HAS_AVM_JUNK_BYTES" == "y" ]; then echo0 "removing AVM SquashFS junk bytes" [ "$FREETZ_HAS_UPDATE_FILESYSTEM_IMAGE" == "y" ] && JUNK_BYTES_FILE="${FIRMWARE_DIR}/${FILESYSTEM_IMAGE}" || JUNK_BYTES_FILE="$KERNEL" if [ "$FREETZ_VERBOSITY_LEVEL" -lt 2 ]; then "$TOOLS_DIR/remove-junk-bytes" "$JUNK_BYTES_FILE" "$JUNK_BYTES_FILE.nojunk" >/dev/null 2>&1 else "$TOOLS_DIR/remove-junk-bytes" "$JUNK_BYTES_FILE" "$JUNK_BYTES_FILE.nojunk" fi [ $? -eq 0 ] || error 1 "AVM SquashFS junk bytes not found" mv -f "$JUNK_BYTES_FILE.nojunk" "$JUNK_BYTES_FILE" fi "$RMTICHKSUM" -f "${KERNEL}" > /dev/null "$RMTICHKSUM" -f "${FIRMWARE_DIR}/${FILESYSTEM_IMAGE}" > /dev/null mkdir -p "$KERNEL_DIR" if [ "${FREETZ_HAS_UPDATE_FILESYSTEM_IMAGE}" == "y" ]; then cp "${KERNEL}" "${RAW_KERNEL}" echo "unpacking update image" modunsqfs "$FILESYSTEM_CORE_DIR" "${FIRMWARE_DIR}/${FILESYSTEM_IMAGE}" [ ! -r "$RAW_KERNEL" -o ! -r "$FILESYSTEM" ] && error 1 "copying kernel or filesystem image failed" echo "unpacking filesystem image" modunsqfs "$FILESYSTEM_DIR" "$FILESYSTEM" else echo "splitting kernel image" ( cd "$KERNEL_DIR" && "${TOOLS_DIR}/${FINDSQUASHFS_TOOL}" "../${FIRMWARE_SUBDIR}/${KERNEL_IMAGE}" > /dev/null 2>&1 ) if [ ! -r "$RAW_KERNEL" -o ! -r "$FILESYSTEM" ]; then if [ -r "${FIRMWARE_DIR}/${FILESYSTEM_IMAGE}" ] && [ $(stat -c %s "${FIRMWARE_DIR}/${FILESYSTEM_IMAGE}") -gt 0 ]; then _config_hint=" - maybe you should configure a firmware with FREETZ_HAS_UPDATE_FILESYSTEM_IMAGE" fi error 1 "kernel splitting failed${_config_hint}" fi echo "unpacking filesystem image" modunsqfs_lzma "$FILESYSTEM_DIR" "$FILESYSTEM" fi if [ -r "$AVMPLUGINS" ]; then echo0 "unpacking AVM plugins" mkdir -p "$AVMPLUGINS_DIR" "$UNTAR" -xf "$AVMPLUGINS" -C "$AVMPLUGINS_DIR" || exit 1 for i in "${AVMPLUGINS_DIR}/var/"*.image; do AVMPLUGIN="${i##*/plugin-}" AVMPLUGIN="${AVMPLUGIN%\.image}" echo2 "$AVMPLUGIN image" modunsqfs_lzma "$AVMPLUGINS_DIR/plugin-${AVMPLUGIN}" "$i" > /dev/null done chmod -R +w "$AVMPLUGINS_DIR" fi if [ ! -r "$FILESYSTEM_DIR/var" ]; then error 1 "could not unpack the filesystem image" fi if [ ! -r "$VARTAR" ]; then error 1 "no var.tar found" fi echo "unpacking var.tar" mkdir "$VARTAR_DIR" "$UNTAR" -xpf "$VARTAR" -C "$VARTAR_DIR" || exit 1 echo -e "done.\n" # Unpack secondary firmware image if [ -n "$FIRMWARE2" ]; then rm -rf "${DIR}/.tk" "$0" -u -d "${DIR}/.tk" "$FIRMWARE2" | sed "s/STEP 1: UNPACK/STEP 1B: UNPACK SECONDARY${FORCE_UNPACK}/" fi # Create "unpacked" marker, recording exactly *what* was unpacked (MD5) echo "$FIRMWARE_MD5" > "$UNPACKED_FILE" fi echo0 -n -b "$SKIP_UNPACK" ############################################### # Lets copy and modify the unpacked firmware ## ############################################### MOD_DIR="${DIR}/modified" FIRMWARE_MOD_DIR="${MOD_DIR}/${FIRMWARE_SUBDIR}" FILESYSTEM_MOD_DIR="${MOD_DIR}/${FILESYSTEM_SUBDIR}" FILESYSTEM_CORE_MOD_DIR="${MOD_DIR}/${FILESYSTEM_CORE_SUBDIR}" EXTERNAL_MOD_DIR="${MOD_DIR}/${EXTERNAL_SUBDIR}" KERNEL_MOD_DIR="${MOD_DIR}/${KERNEL_SUBDIR}" AVMPLUGINS_MOD_DIR="${KERNEL_MOD_DIR}/${AVMPLUGINS_SUBDIR}" AVMPLUGINS_FILESYSTEM_MOD_DIR="${FILESYSTEM_MOD_DIR}/usr/share/avmplugins" VARTAR_MOD_DIR="${KERNEL_MOD_DIR}/${VARTAR_SUBDIR}" KERNEL_MOD="${FIRMWARE_MOD_DIR}/${KERNEL_IMAGE}" FILESYSTEM_MOD="${FIRMWARE_MOD_DIR}/${FILESYSTEM_IMAGE}" RAW_KERNEL_MOD="${KERNEL_MOD_DIR}/${RAW_KERNEL_FILE}" RAW_FILESYSTEM_MOD="${KERNEL_MOD_DIR}/${RAW_HIDDEN_FILE}" if [ "${FREETZ_HAS_UPDATE_FILESYSTEM_IMAGE}" == "y" ]; then CORE_FILESYSTEM_MOD="${FILESYSTEM_CORE_MOD_DIR}/${FILESYSTEM_CORE_IMAGE}" else CORE_FILESYSTEM_MOD="$RAW_FILESYSTEM_MOD" fi VARTAR_MOD="${FILESYSTEM_MOD_DIR}/${VARTAR_FILE}" PACKAGES_DIR="${PACKAGES_DIR_ROOT}/target-${FREETZ_TARGET_ARCH}_uClibc-${FREETZ_TARGET_UCLIBC_VERSION}" TARGET_SPECIFIC_ROOT_DIR="${PACKAGES_DIR}/root" HTML_MOD_DIR="${FILESYSTEM_MOD_DIR}/${HTML_SUBDIR}" # HTML_LANG_MOD_DIR can't be defined here. eg: ${FILESYSTEM_MOD_DIR}/usr/www/all # HTML_SPEC_MOD_DIR can't be defined here. eg: ${FILESYSTEM_MOD_DIR}/usr/www/all/html/de MODULES_DIR="${FILESYSTEM_MOD_DIR}/${MODULES_SUBDIR}" [ "$FREETZ_SQUASHFS_BLOCKSIZE" ] || FREETZ_SQUASHFS_BLOCKSIZE=$("$UNSQUASHFS_LZMA" -s "$FILESYSTEM" 2>/dev/null | sed -nr 's/Block size ([0-9]+)/\1/p') if [ "$FREETZ_SIZEINFO_COMPRESSED" == "y" ]; then let FILESYSTEM_BLOCKSIZE_KB=$FREETZ_SQUASHFS_BLOCKSIZE/1024 SIZEINFO_CACHEDIR=${PACKAGES_DIR}/freetzcachedsizes mkdir -p ${SIZEINFO_CACHEDIR} fi function sizeinfo() { [ "$FREETZ_VERBOSITY_LEVEL" -lt 1 ] && return #formated output if [ $# -eq 1 ]; then if [ "$FREETZ_SIZEINFO_COMPRESSED" != "y" ]; then echo1 "$1" else echo1 -n "$(printf "%-29s " "$1" | sed 's/ /\./g;s/\.\./ ./;s/\.(addon)/ (addon)/')" fi return fi [ "$FREETZ_SIZEINFO_COMPRESSED" != "y" ] && return #cache file local sizeinfo_mode=$1 shift case $sizeinfo_mode in lib) #libraries: multiple files local shash="$(ls -l $@ | sort | $MD5SUM)" local sfile="${SIZEINFO_CACHEDIR}/$(echo $@ | sed -rn 's!.*/(.*)\.so.*!\1!p').sizeinfo.MD5_${shash/ */}.BS_${FILESYSTEM_BLOCKSIZE_KB}" ;; mod) #modules: one .ko file local shash="$(ls -l $1 | $MD5SUM)" local sfile="${SIZEINFO_CACHEDIR}/${1##*/}.sizeinfo.MD5_${shash/ */}.BS_${FILESYSTEM_BLOCKSIZE_KB}" ;; pkg) #packages: files (without .excluded) local shash="$(echo $* | sort | $MD5SUM)" local sfile="${1}/.sizeinfo.MD5_${shash/ */}.BS_${FILESYSTEM_BLOCKSIZE_KB}" shift ;; add) #addons: one directory local shash="$(find $1 -type f -exec ls -l {} ';' | $MD5SUM)" local sfile="${SIZEINFO_CACHEDIR}/${1##*/}.sizeinfo.MD5_${shash/ */}.BS_${FILESYSTEM_BLOCKSIZE_KB}" ;; *) echo "invalid" return ;; esac #compressed size if [ ! -s "$sfile" ]; then if [ $# -eq 0 ]; then echo -n " 0.00 Kb (uncompressed: 0.00 Kb)" > ${sfile} else local tempf=/tmp/freetz-sizeinfo-$$.tmp $TOOLS_DIR/$MKSQUASHFS_TOOL $@ $tempf $MKSQUASHFS_OPTIONS -b $FREETZ_SQUASHFS_BLOCKSIZE 2>/dev/null | grep -A1 ^Filesystem \ | sed -n 'N;s!Filesystem size \(.*\)ytes (.*\n.*(\(.*\)ytes.*$!\1 \2!p' \ | awk '{printf "%8s%3s (uncompressed:%8s%3s)",$1,$2,$3,$4}' > ${sfile} rm -rf $tempf 2>/dev/null fi fi #uncompressed size if [ "$FREETZ_SIZEINFO_UNCOMPRESSED" = "y" ]; then cat ${sfile} else cat ${sfile} | sed 's/(uncompressed.*//' fi echo } # show avm image details avm_fw_produkt="$(sed -rn 's/export CONFIG_PRODUKT_NAME=.*([0-9]{3}[0-9V].*)"/\1/p' ${FILESYSTEM_DIR}/etc/init.d/rc.conf | head -n1)" # newer 4-digits [ -z "$avm_fw_produkt" ] && avm_fw_produkt="$(sed -rn 's/^HW=[0-9]* OEM=all _PRODUKT_NAME=.*([0-9]{4}).*/\1/p' ${FILESYSTEM_DIR}/etc/init.d/rc.init)" #older 4-digits [ -z "$avm_fw_produkt" ] && avm_fw_produkt="$(sed -n 's/^HW=[0-9]* OEM=all _PRODUKT_NAME=\(FRITZ!Box\|Speedport\)#//p' ${FILESYSTEM_DIR}/etc/init.d/rc.init |head -n1| sed 's/#//g;s/Annex.//;s/WLAN/-&/g;s/^$/FritzBox/g')" #oldest, fon-sl-wlan etc avm_fw_produkt="${avm_fw_produkt% }" avm_fw_language="$(sed -n 's/^language /_/p' ${FILESYSTEM_DIR}/etc/default.language)" #primary language avm_fw_language="$avm_fw_language$(for x in $(ls ${FILESYSTEM_DIR}/etc/htmltext_??.db 2>/dev/null| sed 's/.*_//g;s/\.db//g'); do [ "_$x" != "$avm_fw_language" ] && echo -en "-$x"; done; echo)" # other languages avm_fw_major="$(sed -rn 's/^export CONFIG_VERSION_MAJOR="(.*)"/\1/p' ${FILESYSTEM_DIR}/etc/init.d/rc.conf | tail -n1)" # newer firmware [ -z "$avm_fw_major" ] && avm_fw_major="$(sed -n 's/^HW=[0-9].*VERSION_MAJOR=//p' ${FILESYSTEM_DIR}/etc/init.d/rc.init)" # older firmware avm_fw_version="$(sed -n 's/^export FIRMWARE_VERSION=.*}//p' ${FILESYSTEM_DIR}/etc/version)" avm_fw_labor="$(sed -rn 's/^export CONFIG_LABOR_ID_NAME="(.*)"/-\1/p' ${FILESYSTEM_DIR}/etc/init.d/rc.conf)" avm_fw_revision="$(sed -n '/--project)$/{N;s/.*echo //p}' ${FILESYSTEM_DIR}/etc/version)" avm_fw_date="$(sed -rn 's/^export FIRMWARE_DATE="(.*)"/\1/p' ${FILESYSTEM_DIR}/etc/version)" echo1 -l "detected firmware ${avm_fw_produkt/ /-}$avm_fw_language $avm_fw_major$avm_fw_version$avm_fw_labor rev$avm_fw_revision ($avm_fw_date)\n" if [ "$DO_MOD" -gt 0 ]; then echo0 -b "STEP 2: MODIFY" # Check if firmware is unpacked if [ ! -r "$UNPACKED_FILE" ]; then error 1 "firmware image has to be unpacked before modifying" fi rm -rf "$MOD_DIR" rm -f "${DIR}/.modified" # Copy the unpacked directory mkdir -p "$MOD_DIR" [ "$FREETZ_HAS_AVM_UDEV" == y ] || exclude_dev="--exclude=./filesystem/dev" "$TAR" -c -C "$ORG_DIR" $exclude_dev . | "$TAR" -x -C "$MOD_DIR" || exit 1 # Fix some permissions chmod -R u+w "$FILESYSTEM_MOD_DIR" find "${FILESYSTEM_MOD_DIR}" "${VARTAR_MOD_DIR}" -type d -exec chmod 755 {} '+' # Give all users write permissions to /var/tmp to allow it to be used as a temp-directory. # Set sticky bit to prevent users from deleting/renaming files they are not the owners of. # NB: The permissions set are the regular temp-directory permissions on Unix-like systems. chmod 1777 "${VARTAR_MOD_DIR}/var/tmp" echo0 -n "applying symlinks, deleting additional webinterfaces in:" oems="$(grep 'for i in avm' "${FIRMWARE_MOD_DIR}/var/install" | head -n 1 | sed -e 's/^.*for i in\(.*\); do.*$/\1/')" for webdir in \ ${FILESYSTEM_MOD_DIR}/usr/www \ ${FILESYSTEM_MOD_DIR}/usr/www.nas \ ${FILESYSTEM_MOD_DIR}/usr/www.myfritz \ ; do if [ -d ${webdir}/avm* ]; then echo0 -n " ${webdir#${FILESYSTEM_MOD_DIR}/}" mv ${webdir}/avm* ${webdir}/all for i in $oems; do rm -rf ${webdir}/$i ln -s all ${webdir}/$i done fi done echo0 echo0 "applying patches" # Include patching helper function (modpatch) . "${TOOLS_DIR}/freetz_patch" || error 1 "cannot find script freetz_patch" PATCHES_DEVICES_DIR_EXTRA="${PATCHES_DEVICES_DIR}/${FREETZ_TYPE_PREFIX_SERIES_SUBDIR}/${FREETZ_TYPE_PREFIX%_*}" PATCHES_DEVICES_DIR_MULTI="${PATCHES_DEVICES_DIR}/${FREETZ_TYPE_PREFIX_SERIES_SUBDIR}" echo1 "applying patches: ${FREETZ_TYPE_PREFIX}${FREETZ_TYPE_PREFIX_LABOR_FIRMWARE}-${FREETZ_TYPE_LANGUAGE} (${FREETZ_TYPE_PREFIX_SERIES_SUBDIR})" # Apply patches if [ ! -d "$PATCHES_DEVICES_DIR_EXTRA" -a ! -d "$PATCHES_DEVICES_DIR_MULTI" ]; then error 1 "missing $PATCHES_DEVICES_DIR_EXTRA" fi # Execute version specific patch scripts for j in ${PATCHES_DIR} $PATCHES_DEVICES_DIR_MULTI $PATCHES_DEVICES_DIR_EXTRA; do for i in $j/*.sh $j/${FREETZ_TYPE_LANGUAGE}/*.sh; do [ -r "$i" ] || continue echo2 "applying patch file $i" . $i done done # Now we are in place to check html directory for i in all/en all; do if [ -d "${HTML_MOD_DIR}/$i" ]; then HTML_LANG_MOD_DIR="${HTML_MOD_DIR}/$i" break fi done [ -z "$HTML_LANG_MOD_DIR" ] && error 1 "No HTML directory given." # Now check language specific html directory for i in de en; do if [ -d "${HTML_LANG_MOD_DIR}/html/$i" ]; then HTML_SPEC_MOD_DIR="${HTML_LANG_MOD_DIR}/html/$i" break fi done [ -z "$HTML_SPEC_MOD_DIR" ] && error 1 "No language specific HTML directory given." # Apply (general, version specific, language specific) patches shopt -s nullglob for j in ${PATCHES_DIR} $PATCHES_DEVICES_DIR_MULTI $PATCHES_DEVICES_DIR_EXTRA; do for i in $j/*.patch $j/${FREETZ_TYPE_LANGUAGE}/*.patch; do modpatch "$FILESYSTEM_MOD_DIR" "$i" done done shopt -u nullglob echo1 "creating symlinks /tmp, /mod and /home" rm -rf "$FILESYSTEM_MOD_DIR"/tmp ln -s var/{tmp,mod} "$FILESYSTEM_MOD_DIR"/ ln -s var/mod/home "$FILESYSTEM_MOD_DIR"/ echo1 "creating /mnt and /opt" mkdir -p "$FILESYSTEM_MOD_DIR"/mnt # 7390: /opt is symlink to /var/InternerSpeicher/opt [ ! -L "$FILESYSTEM_MOD_DIR"/opt ] && mkdir -p "$FILESYSTEM_MOD_DIR"/opt # Set version and options SUBVERSION_FILE="${BASE_DIR}/.version" FIRMWAREVERSION_FILE="${FILESYSTEM_MOD_DIR}/etc/.version" FIRMWAREVERSION="$(cat $FIRMWAREVERSION_FILE)" PACKAGES_LIST_FILE="${BASE_DIR}/.packages" if [ ! -r "$SUBVERSION_FILE" ]; then error 1 "cannot determine version" fi if [ -d .svn ]; then # be compatible: older versions of svnversion need WC_PATH if REVISION="$(svnversion . 2>/dev/null | tr ":" "_")"; then [ "${REVISION:0:6}" == "export" ] && REVISION="" fi elif [ -d .git ]; then REVISION="$(git log 2>/dev/null | sed -rn 's!.*git-svn-id.*\@([^ ]*).*!\1!p' | head -n1)" fi [ -n "$REVISION" ] && REVISION="-$REVISION" SUBVERSION="$(cat $SUBVERSION_FILE)${REVISION}" #delete .packages file rm -f "${PACKAGES_LIST_FILE}" for i in $(set|grep -i "^FREETZ_REMOVE_.*=y$"|sed -e "s/^.\{14\}//;s/=.*//"|tr [A-Z] [a-z]|sort); do OPTIONS+=" -$i" done OPTIONS_ADD=" +busybox" for i in $(set|grep -i "^FREETZ_PATCH_.*=y$"|sed -e "s/^.\{13\}//;s/=.*//"|tr [A-Z] [a-z]); do OPTIONS_ADD+=" +$i" done for pkg in $(static_packages) $(static_addons); do OPTIONS_ADD+=" +$pkg" echo "$pkg" >> "${PACKAGES_LIST_FILE}" done if [ "$FIRMWARE_NOCOMPILE" != "1" -a "$FREETZ_REPLACE_KERNEL" == "y" -a "$FWMOD_PATCH_TEST" != "y" ]; then KERNEL_SUBVERSION_FILE="${KERNEL_REP_DIR}/.version-${FREETZ_KERNEL_LAYOUT}-${FREETZ_AVM_VERSION_STRING}" if [ ! -r "$KERNEL_SUBVERSION_FILE" ]; then error 1 "cannot determine kernel version" fi KERNEL_SUBVERSION="$(cat $KERNEL_SUBVERSION_FILE)" OPTIONS_ADD+=" +kernel ($KERNEL_SUBVERSION)" fi for i in $(echo ${OPTIONS_ADD}|sed -e's: +:\n+:g'|sort); do OPTIONS+=" $i" done echo1 "setting freetz-version '${SUBVERSION}'" echo "$SUBVERSION" > "${FILESYSTEM_MOD_DIR}/etc/.freetz-version" if [ "$FREETZ_MODIFY_AVM_VERSION" == "y" ]; then echo1 "setting AVM firmware subversion '${SUBVERSION}'" echo "$SUBVERSION" > "${FILESYSTEM_MOD_DIR}/etc/.subversion" sed -i -e "s/\export\ FIRMWARE_SUBVERSION=.*\$/export\ FIRMWARE_SUBVERSION=\"${SUBVERSION}\"/g" "${FILESYSTEM_MOD_DIR}/etc/version" if [ ! -e "${FILESYSTEM_MOD_DIR}/etc/init.d/rc.init" ]; then AVM_SUBVERSION=`grep "SUBVERSION=" "${FILESYSTEM_MOD_DIR}/etc/init.d/rc.conf" | sed -e "s/[^-0-9]//g"` sed -i -e "s/SUBVERSION=\"$AVM_SUBVERSION\"/SUBVERSION=\"-$SUBVERSION\"/" "${FILESYSTEM_MOD_DIR}/etc/init.d/rc.conf" fi sed -i -e "s//${SUBVERSION}/g" "${FILESYSTEM_MOD_DIR}/usr/bin/system_status" sed -i -e "s//${OPTIONS}/g" "${FILESYSTEM_MOD_DIR}/usr/bin/system_status" fi # Execute general patch scripts for i in "${PATCHES_SCRIPTS_DIR}/"*.sh; do [ -r "$i" ] || continue echo2 "applying patch file $i" . $i done # stop execution if in patch test mode if [ "$FWMOD_PATCH_TEST" == "y" ]; then echo0 -b "Patch test mode: exiting without error." exit fi # remove oems [ "$FREETZ_VERBOSITY_LEVEL" -ge 1 ] && echo -n "${L1}removing oem:" oem_removed=0 oem_kept=0 oem_list= oems=$(grep -E 'for i in (avm|tcom)' "${FIRMWARE_MOD_DIR}/var/install" | head -n 1 | sed -e 's/^.*for i in\(.*\); do.*$/\1/') if [ -z "$oems" ]; then error 1 "no oems found" fi ln -sf /usr/www/cgi-bin/freetz_status "${HTML_LANG_MOD_DIR}/cgi-bin/freetz_status" [ "$FREETZ_PACKAGE_WOL_CGI" == "y" ] && ln -sf /usr/www/cgi-bin/freetz_wol "${HTML_LANG_MOD_DIR}/cgi-bin/freetz_wol" for i in $oems; do if [ "$(eval "echo \"\$FREETZ_REMOVE_BRANDING_${i}\"")" == "y" ]; then [ "$FREETZ_VERBOSITY_LEVEL" -ge 1 ] && echo -n " $i" # delete webinterface symlinks otherwise user can choose branding in status.cgi rm -rf "${FILESYSTEM_MOD_DIR}/usr/www/${i}" rm -rf "${FILESYSTEM_MOD_DIR}/usr/www.nas/${i}" rm -rf "${FILESYSTEM_MOD_DIR}/usr/www.myfritz/${i}" find ${FILESYSTEM_MOD_DIR}/etc/default.* -name "*${i}*" | xargs rm -rf oem_removed=1 else oem_list+=" $i" oem_kept=1 fi done if [ "$FREETZ_VERBOSITY_LEVEL" -ge 1 ]; then [ "$oem_removed" -eq 0 ] && echo -n " none" echo fi if isFreetzType W501V; then oem_list="tcom avm" fi sed -i -r -e 's/for i in (avm|tcom).*; do/for i in '"$oem_list"' ; do/g' "${FIRMWARE_MOD_DIR}/var/install" if [ "$oem_kept" -eq 0 ]; then error 1 "please choose at least one OEM (branding) in menuconfig: AVM, 1&1, Freenet etc." fi # Copy selected avmplugins into the firmware if [ "$FREETZ_AVMPLUGINS_ENABLED" == "y" ]; then echo0 "installing AVM plugins" echo "#" > ${FILESYSTEM_MOD_DIR}/sbin/start_plugin.sh rm -rf ${FIRMWARE_MOD_DIR}/${AVMPLUGINS_FILE} mkdir "${AVMPLUGINS_FILESYSTEM_MOD_DIR}" for i in `find "${AVMPLUGINS_MOD_DIR}" -maxdepth 1 -type d -name var -prune -false , -type d -name "plugin-*" 2>/dev/null`; do AVMPLUGIN="${i##*plugin-}" if [ "$(eval "echo \"\$FREETZ_AVMPLUGINS_$(echo "$AVMPLUGIN" | tr [:lower:] [:upper:])\"")" == "y" ]; then echo1 "$AVMPLUGIN plugin" cp -a "${AVMPLUGINS_MOD_DIR}/plugin-${AVMPLUGIN}" "${AVMPLUGINS_FILESYSTEM_MOD_DIR}/plugin-${AVMPLUGIN}" ln -s "/usr/share/avmplugins/plugin-${AVMPLUGIN}" "${VARTAR_MOD_DIR}/var/plugin-${AVMPLUGIN}" for module in `cd "${AVMPLUGINS_FILESYSTEM_MOD_DIR}/plugin-${AVMPLUGIN}";find -type f -name "*.ko"`; do echo2 "moving ${module##*/} to standard modules dir" mv "${AVMPLUGINS_FILESYSTEM_MOD_DIR}/plugin-${AVMPLUGIN}/$module" "${FILESYSTEM_MOD_DIR}/$module" done case "$AVMPLUGIN" in tam) modsed \ "s/ CONFIG_TAM_ONRAM=.*$/ CONFIG_TAM_ONRAM=\"n\"/g" \ "${FILESYSTEM_MOD_DIR}/etc/init.d/rc.conf" ;; esac fi done fi if [ "$FREETZ_INSTALL_BASE" == "y" ]; then echo "installing mod base" MOD_CRON="${VARTAR_MOD_DIR}/var/spool/cron/crontabs" MOD_ROOT="${VARTAR_MOD_DIR}/var/mod" # Remove symlink before creating directory rm -rf ${VARTAR_MOD_DIR}/var/spool mkdir -p "$MOD_CRON" mkdir -p "${MOD_ROOT}/pkg" "${MOD_ROOT}/home" "${MOD_ROOT}/lib" "${MOD_ROOT}/root" mkdir -p "${MOD_ROOT}/bin" "${MOD_ROOT}/sbin" mkdir -p "${MOD_ROOT}/var/cache" mkdir -p "${MOD_ROOT}/usr/bin" "${MOD_ROOT}/usr/sbin" "${MOD_ROOT}/usr/share" \ "${MOD_ROOT}/usr/lib" "${MOD_ROOT}/usr/lib/cgi-bin" "${MOD_ROOT}/usr/lib/freetz" mkdir -p "${MOD_ROOT}/etc/conf" "${MOD_ROOT}/etc/init.d" "${MOD_ROOT}/etc/reg" ln -s /tmp/flash/mod/.profile "${MOD_ROOT}/root/.profile" # AVM compatibility symlink ln -s ../sys "${VARTAR_MOD_DIR}/var/sysfs" echo "root:x:0:0:root:/mod/root:/bin/sh" > "${VARTAR_MOD_DIR}/var/tmp/passwd" echo 'root:$1$$zO6d3zi9DefdWLMB.OHaO.:12332:0:99999:7:::' > "${VARTAR_MOD_DIR}/var/tmp/shadow" echo "root:x:0:" > "${VARTAR_MOD_DIR}/var/tmp/group" echo "users:x:1:" >> "${VARTAR_MOD_DIR}/var/tmp/group" touch "${VARTAR_MOD_DIR}/var/tmp/ethers" touch "${VARTAR_MOD_DIR}/var/tmp/exports" touch "${VARTAR_MOD_DIR}/var/tmp/gshadow" chmod 644 "${VARTAR_MOD_DIR}/var/tmp/passwd" "${VARTAR_MOD_DIR}/var/tmp/group" chmod 600 "${VARTAR_MOD_DIR}/var/tmp/shadow" "${VARTAR_MOD_DIR}/var/tmp/gshadow" # Fix permissions set by AVM, in particular revoke write permissions for g- and o-users. chmod 644 "${VARTAR_MOD_DIR}/var/tmp/hosts" "${VARTAR_MOD_DIR}/var/tmp/resolv.conf" mkdir -p "${VARTAR_MOD_DIR}/var/tmp/onlinechanged" ln -s ../var/tmp/ethers "${FILESYSTEM_MOD_DIR}/etc/ethers" ln -s ../var/tmp/exports "${FILESYSTEM_MOD_DIR}/etc/exports" ln -s ../var/tmp/gshadow "${FILESYSTEM_MOD_DIR}/etc/gshadow" rm -f ${VARTAR_MOD_DIR}/var/*/.dummy echo1 "installing libs" for i in $(set | grep ^FREETZ_LIB_.*=y | grep -v ^FREETZ_LIB_STDCXXLIB); do all_files="" found=0 conf=${i%%=*} [ "$conf" != "${conf%%_WITH_*}" ] && continue # skip suboptions bn=${conf#FREETZ_LIB_} fn=${bn//_/[-+._]} sizeinfo "$bn" for dn in lib usr/lib usr/lib/freetz usr/lib/xtables; do files=$(shopt -s nullglob; echo ${TARGET_SPECIFIC_ROOT_DIR}/$dn/$fn[-.]*so*) if [ -z "$files" ]; then continue; fi found=1 [ -d "${FILESYSTEM_MOD_DIR}/${dn}" ] || mkdir -p "${FILESYSTEM_MOD_DIR}/${dn}" cp -a $files "${FILESYSTEM_MOD_DIR}/${dn}/" all_files="$all_files $files" done if [ "$found" = 0 ]; then warn "Library $bn selected, but no files found" else sizeinfo lib "$all_files" fi done [ "$FREETZ_LIB_libuClibc" == "y" ] && cp -a "${TARGET_SPECIFIC_ROOT_DIR}/lib/libc.so.0" "${FILESYSTEM_MOD_DIR}/lib/" if [ "$FREETZ_SHARE_terminfo" == "y" ]; then echo1 "installing terminfos" for i in $(set | grep ^FREETZ_SHARE_terminfo_.*=y |grep -v '^FREETZ_SHARE_terminfo_showall=' ); do dn=usr/share/terminfo conf=${i%%=*} bn=${conf#FREETZ_SHARE_terminfo_} fn=$(echo "$bn" | sed 's/MINUS/-/g;s/PLUS/+/g;s/\DOT/./g') echo2 "$fn" fn="${fn:0:1}/$fn" file="${TARGET_SPECIFIC_ROOT_DIR}/$dn/$fn" if [ ! -e "$file" ]; then warn "Terminfo $bn selected, but no file found" continue; fi dest="${FILESYSTEM_MOD_DIR}/$dn/${fn:0:1}" [ -d "$dest" ] || mkdir -p "$dest" cp -a $file "$dest/" done fi else error 1 "installation of base system is mandatory" fi if [ "$FIRMWARE_NOCOMPILE" != "1" ]; then [ "$FREETZ_REPLACE_BUSYBOX" != "y" ] && error 1 "installation of busybox replacement is mandatory" echo0 "installing busybox" echo1 "replacing busybox" [ ! -r "${PACKAGES_DIR}/busybox/busybox" ] && error 1 "cannot find busybox replacement" cp -pf "${PACKAGES_DIR}/busybox/busybox" "${FILESYSTEM_MOD_DIR}/bin/busybox" echo1 "installing symlinks" [ ! -r "${PACKAGES_DIR}/busybox/busybox.links" ] && error 1 "cannot find busybox links" # Remove old busybox links # be compatible: do not use -delete (not found in older versions of find) find "$FILESYSTEM_MOD_DIR" \( -lname "busybox" -or -lname "*/busybox" \) -print0 | xargs -0 rm # Install new busybox links for link in $(cat "${PACKAGES_DIR}/busybox/busybox.links"); do LINK_DIR="$(dirname "$link")" LINK_NAME="$(basename "$link")" case "$LINK_DIR" in /) BUSYBOX_PATH="bin/busybox" ;; /bin) BUSYBOX_PATH="busybox" ;; /sbin) BUSYBOX_PATH="../bin/busybox" ;; /usr/bin|/usr/sbin) BUSYBOX_PATH="../../bin/busybox" ;; *) error 1 "unknown installation directory: $link" ;; esac ln -sf "$BUSYBOX_PATH" "${FILESYSTEM_MOD_DIR}${LINK_DIR}/$LINK_NAME" || error 1 "could not create link for $link" done || exit 1 fi if [ "$NOCOMPILE" != "1" -a "$FREETZ_REPLACE_KERNEL" == "y" ]; then echo0 "replacing kernel" if [ ! -r "${KERNEL_REP_DIR}/kernel-${FREETZ_KERNEL_LAYOUT}-${FREETZ_AVM_VERSION_STRING}.bin" ]; then error 1 "can't find kernel for ref ${FREETZ_KERNEL_LAYOUT}-${FREETZ_AVM_VERSION_STRING}" fi echo1 "replacing kernel-${FREETZ_KERNEL_LAYOUT}-${FREETZ_AVM_VERSION_STRING} (${KERNEL_SUBVERSION})" cp "${KERNEL_REP_DIR}/kernel-${FREETZ_KERNEL_LAYOUT}-${FREETZ_AVM_VERSION_STRING}.bin" "$RAW_KERNEL_MOD" fi if [ "$FREETZ_REPLACE_KERNEL" == "y" -o -n "$(set|grep ^FREETZ_MODULE_.*=y)" ]; then [ "$FREETZ_STRIP_MODULES_FREETZ" == "y" ] && strip_output=" and stripping" echo0 "installing$strip_output modules" for i in \ $( \ cd "${KERNEL_REP_DIR}/modules-${FREETZ_KERNEL_LAYOUT}-${FREETZ_AVM_VERSION_STRING}" && \ find . -type d -name .svn -prune -false , -type f \( -name modules.dep -o -name "*.ko" \) \ ) do bn="$(basename "$i")" if [ "$FREETZ_MODULES_ALL" = "y" -o "$(eval "echo \"\$FREETZ_MODULE_$(echo "${bn%\.ko}" | tr '\-+' '_x')\"")" == "y" ]; then sizeinfo "$bn" ko_file_src="${KERNEL_REP_DIR}/modules-${FREETZ_KERNEL_LAYOUT}-${FREETZ_AVM_VERSION_STRING}/${i}" ko_path_dst="${MODULES_DIR}/kernel/$(dirname "$i")" [ -d "$ko_path_dst" ] || mkdir -p "$ko_path_dst" cp -a $ko_file_src "$ko_path_dst/" if [ "$FREETZ_STRIP_MODULES_FREETZ" == "y" ]; then ${ABS_BASE_DIR}/toolchain/kernel/bin/${FREETZ_KERNEL_CROSS}strip -p --strip-unneeded \ --remove-section={.comment,.pdr,.mdebug.abi32,.note.gnu.build-id} "$ko_path_dst/$bn" fi sizeinfo mod "$ko_path_dst/$bn" fi done echo1 "generating modules.dep" [ "$FREETZ_VERBOSITY_LEVEL" -ge 2 ] && errsyms="-e" NM=$NM ${TOOLS_DIR}/depmod.pl $errsyms -b "$MODULES_DIR" \ -F ${KERNEL_REP_DIR}/System-${FREETZ_KERNEL_LAYOUT}-${FREETZ_AVM_VERSION_STRING}.map # add plugin kernel modules for 7270 if plugins are not enabled if [ "$FREETZ_TYPE_7270_V1" == "y" -a ! "$FREETZ_AVMPLUGINS_ENABLED" == "y" ]; then echo -e "kernel/drivers/net/rfcntl/rfcntl.ko: kernel/drivers/char/audio/avm_audio.ko\nkernel/drivers/char/audio/avm_audio.ko:\n" >> $MODULES_DIR/modules.dep fi fi echo0 "installing packages" for pkg in $(static_packages); do sizeinfo "$pkg" pkg_name=$(pkg_name "$pkg") "$TAR" -c -C "${PACKAGES_DIR}/${pkg}/root" \ $( [ -r "${PACKAGES_DIR}/${pkg}/.exclude" ] \ && echo "--exclude-from=${PACKAGES_DIR}/${pkg}/.exclude" ) . | \ "$TAR" -x -C "$FILESYSTEM_MOD_DIR" || exit 1 [ -d "${PACKAGES_DIR}/${pkg}/${VARTAR_SUBDIR}" ] && \ $( "$TAR" -c -C "${PACKAGES_DIR}/${pkg}/${VARTAR_SUBDIR}" . | \ "$TAR" -x -C ${VARTAR_MOD_DIR} || exit 1 ) [ -r "${PACKAGES_DIR}/${pkg}/.language" ] && \ modlang "${PACKAGES_DIR}/${pkg}/.language" "${FILESYSTEM_MOD_DIR}" grep -q "^$pkg_name$" "${FILESYSTEM_MOD_DIR}/etc/static.pkg" >/dev/null 2>&1 || ( echo "$pkg_name" >> "${FILESYSTEM_MOD_DIR}/etc/static.pkg" ) pkgfiles="$(find ${PACKAGES_DIR}/${pkg}/root -type f)" excludes="$(cat ${PACKAGES_DIR}/${pkg}/.exclude 2>/dev/null | sed ':a;N;$!ba;s/\n/|/g')" [ -n "$excludes" ] && pkgfiles=$(echo "$pkgfiles" | grep -vE "$excludes" ) sizeinfo pkg "${PACKAGES_DIR}/${pkg}" $pkgfiles done for pkg in $(static_addons); do sizeinfo "$pkg (addon)" pkg_name=$(pkg_name "$pkg") if [ -e "${ADDON_DIR}/${pkg}/etc/init.d/rc.${pkg_name}" ]; then echo "NOTICE: addon '$pkg' is in old-style format (no language support)." 1>&2 "$TAR" -c -C "${ADDON_DIR}/${pkg}" . | "$TAR" -x -C "$FILESYSTEM_MOD_DIR" || exit 1 else "$TAR" -c -C "${ADDON_DIR}/${pkg}/root" \ $( [ -r "${ADDON_DIR}/${pkg}/.exclude" ] \ && echo "--exclude-from=${ADDON_DIR}/${pkg}/.exclude" \ ) . | \ "$TAR" -x -C "$FILESYSTEM_MOD_DIR" || exit 1 [ -d "${ADDON_DIR}/${pkg}/${VARTAR_SUBDIR}" ] && \ $( "$TAR" -c -C "${ADDON_DIR}/${pkg}/${VARTAR_SUBDIR}" . | \ "$TAR" -x -C ${VARTAR_MOD_DIR} || exit 1 ) [ -r "${ADDON_DIR}/${pkg}/.language" ] && \ modlang "${ADDON_DIR}/${pkg}/.language" "${FILESYSTEM_MOD_DIR}" fi grep -q "^$pkg_name$" "${FILESYSTEM_MOD_DIR}/etc/static.pkg" >/dev/null 2>&1 || ( echo "$pkg_name" >> "${FILESYSTEM_MOD_DIR}/etc/static.pkg" ) sizeinfo add "${ADDON_DIR}/${pkg}" done if [ -x "${BASE_DIR}/fwmod_custom" ]; then echo "invoking custom script" # syntax check $SHELL -n "${BASE_DIR}/fwmod_custom" if [ $? -ne 0 ]; then error 1 "syntax error in custom script" fi ( cd "$MOD_DIR" && ../../fwmod_custom all ) || exit 1 if [ $? -ne 0 ]; then error 1 "custom script returned error" fi fi # Processing some options, must be done after base package is in place if [ "$FREETZ_INSTALL_BASE" == "y" ]; then echo0 "processing mod base options" # color scheme if [ "$FREETZ_STYLE" == "grey" ]; then echo1 "setting grey style as default" ln -s colorscheme-grey.css ${FILESYSTEM_MOD_DIR}/usr/share/style/colorscheme.css else echo1 "setting colored style as default" ln -s colorscheme-colored.css ${FILESYSTEM_MOD_DIR}/usr/share/style/colorscheme.css fi # favicon if [ "$FREETZ_FAVICON_STRING" != "none" ]; then echo1 "adding favicon(s) (${FREETZ_FAVICON_STRING})" cp "${FAVICON_DIR}/${FREETZ_FAVICON_STRING}/freetz.ico" "${FILESYSTEM_MOD_DIR}/usr/share/favicon.ico" ln -s "../share/favicon.ico" "${FILESYSTEM_MOD_DIR}/usr/mww/favicon.ico" if [ -e "${FAVICON_DIR}/${FREETZ_FAVICON_STRING}/box.ico" ]; then cp "${FAVICON_DIR}/${FREETZ_FAVICON_STRING}/box.ico" "${HTML_LANG_MOD_DIR}/html/favicon.ico" ln -fs "./html/favicon.ico" "${HTML_LANG_MOD_DIR}/favicon.ico" fi fi # security level echo1 "patching security level" sed -i -e "s/sec_level=1/sec_level=$FREETZ_SECURITY_LEVEL/g" ${FILESYSTEM_MOD_DIR}/usr/lib/libmodcgi.sh # external [ ! "$EXTERNAL_ENABLED" == "y" ] && echo1 "rc.external was not integrated into image" # freetz mount [ ! "$FREETZ_PATCH_FREETZMOUNT" == "y" ] && echo1 "libmodmount.sh was not integrated into image" # Box-Info [ "$FREETZ_REMOVE_BOX_INFO" == "y" ] && echo1 "Box-Info cgi was not integrated into image" # FREETZ-Info [ "$FREETZ_REMOVE_FREETZ_INFO" == "y" ] && echo1 "FREETZ-Info cgis were not integrated into image" # Packing .config into image if [ ! "$FREETZ_REMOVE_DOT_CONFIG" == "y" ]; then echo1 "integrating stripped .config file into image" dot_config_file="$MOD_DIR/filesystem/etc/.config" cat "$DOT_CONFIG" | sed -e "s/#.*//g;/^$/d" > "$dot_config_file" fi # logo tagging if [ "$FREETZ_TAGGING_STRING" != "none" ]; then tagging() { [ $# -lt 3 ] && return local tagging_geo="$1" shift local tagging_pos="$1" shift local tagging_arg="$*" local tagging_pic="${TAGGING_DIR}/${FREETZ_TAGGING_STRING}.png" for tagging_file in $tagging_arg; do echo2 "${tagging_file}" composite -dissolve 100% -gravity $tagging_pos -geometry $tagging_geo -quality 100 $tagging_pic $tagging_file $tagging_file [ $? -ne 0 ] && error 1 "tagging failed while processing ${tagging_file#${FILESYSTEM_MOD_DIR}/}" done } echo1 "tagging avm webif (tag by ${FREETZ_TAGGING_STRING})" # newest lua (small logo @left, eg 7270 04.88) tagging "+0+0" "center" $(find ${HTML_MOD_DIR} -name kopfbalken_links.gif) # newer html (big header @top, eg 7320 05.29) tagging "-20+0" "west" $(find ${HTML_MOD_DIR} -name kopfbalken.gif) # older (big header @top, eg 7141 04.76) tagging "+0+0" "west" $(find ${HTML_MOD_DIR} -name fw_header980.gif) # even older (big header @top, eg 7050 04.03) tagging "+0-5" "west" $(find ${HTML_MOD_DIR} -name fw_header.gif) fi fi if [ "$FREETZ_STRIP_LIBRARIES" == "y" ]; then echo0 "shrinking shared libs" . ${TOOLS_DIR}/freetz_mklibs mklibs || error 1 "mklibs returned an error. Please see mklibs.log." fi if [ "$FREETZ_STRIP_MODULES_ALL" == "y" ]; then echo0 "stripping all kernel modules" for i in `find ${MODULES_DIR} -name '*.ko'`; do echo2 $i ${ABS_BASE_DIR}/toolchain/kernel/bin/${FREETZ_KERNEL_CROSS}strip -p --strip-unneeded \ --remove-section={.comment,.pdr,.mdebug.abi32,.note.gnu.build-id} $i done fi if [ "$FREETZ_STRIP_SCRIPTS" == "y" ]; then echo0 "stripping shell scripts" # This is (necessarily) slow because it checks *all* files for f in $(find ${FILESYSTEM_MOD_DIR} -type f); do # Syntax check. Use ash (not bash) because on target we also have ash. # This is the first step because it is faster than 'file'. $BUSYBOX ash -n "$f" 2>/dev/null && # Sometimes the ash syntax check succeeds on binaries. # So we need to check we really have a text file here. file -b --mime-type "$f" | grep -sq '^text/' && # Only strip scripts (possibly also stuff like awk or perl) with # shebang. This excludes dot-included files without shebang, but # anything else would be too unsafe. We do not want plain text # files stripped. grep -sq '#[^!]' "$f" || # continue the loop with the next file if one of the conditions above is false continue # Strip ... STRIP_SCRIPTS_SED_SCRIPT='/^[ \t]*$/d;' # blank lines # TODO: doesn't work because of multiline IFS definitions, i.e. IFS='\t\n' #STRIP_SCRIPTS_SED_SCRIPT+='s/[ \t]+$//;' # trailing white spaces STRIP_SCRIPTS_SED_SCRIPT+='/^[ \t]*#[^!].*/d;' # shell comments (not shebangs) if [ "${f: -3:3}" != ".py" ]; then STRIP_SCRIPTS_SED_SCRIPT+='s/^[ \t]*//g;' # and indentation if it's not a python script fi sed -i -r "${STRIP_SCRIPTS_SED_SCRIPT}" "$f" && echo2 "${f##${FILESYSTEM_MOD_DIR}}" done fi if [ "$FREETZ_STRIP_BINARIES" == "y" ]; then echo0 "stripping leftover unstripped binaries" for i in `find ${FILESYSTEM_MOD_DIR} ! \( -name '*.ko' -o -path '*/usr/www/*' -o -path '*/etc/default*' -o -path '*/lib/modules*' \) \ \( -perm /100 -o -name "*.so*" \) -type f -exec file {} '+'|sed -n 's|^\(.*\):.*MIPS.*not stripped.*|\1|p'`; do echo2 $i chmod u+r $i $STRIP -p --remove-section={.comment,.note,.pdr} $i done fi # External should run after modifying, stripping etc. if [ "$EXTERNAL_ENABLED" == "y" ]; then echo0 "processing external" [ ! -x "$EXTERNAL" ] && error 1 "cannot find the tool $EXTERNAL_TOOL" . "${EXTERNAL}" fi touch "${DIR}/.modified" echo -e "done.\n" fi ########################################### ## Pack, zip, copy the modified firmware ## ########################################### [ "$DO_PACK" -gt 0 ] && action_names+="/PACK" [ "$DO_ZIP" -gt 0 ] && action_names+="/ZIP" [ "$COPY_FS_DIR" ] && action_names+="/COPY" action_names=${action_names##/} # ------------------------------------------------ # -- Common initial actions for pack, zip, copy -- # ------------------------------------------------ if [ "$action_names" ]; then echo0 -b "STEP 3: ${action_names}" if [ ! "$DO_MOD" -gt 0 ]; then echo "WARNING: Modifications (STEP 2) and this step should never" 1>&2 echo " ever be run with different configurations!" 1>&2 echo " This can result in invalid images!!!" 1>&2 fi [ "$FW_IMAGES_DIR" ] && mkdir -p "$FW_IMAGES_DIR" # Check if firmware is unpacked if [ ! -r "$UNPACKED_FILE" ]; then error 1 "firmware image has to be unpacked before packing" fi # Check if firmware is modified by the script if [ ! -r "${DIR}/.modified" ]; then warn "firmware does not seem to be modified by the script" if [ ! -d "$MOD_DIR" ]; then # Copy the unpacked directory cp -r "$ORG_DIR" "$MOD_DIR" fi fi # Remove left over Subversion directories echo1 "checking for left over Subversion directories" find "$MOD_DIR" \( -type d -name '.svn' \) -o -name '.gitignore' | xargs rm -rf # Delete all files that we are going to re-create now rm -f "$VARTAR_MOD" rm -f "$KERNEL_MOD" rm -f "$FILESYSTEM_MOD" rm -f "${DIR}/*.image" modmakedate=$(date +%Y%m%d-%H%M%S) if [ -n "$FREETZ_TYPE_PREFIX_LABOR_FIRMWARE" ]; then modbaselaborname="-rev${avm_fw_revision}${FREETZ_TYPE_PREFIX_LABOR_FIRMWARE}" fi modbaseimagename="${FREETZ_TYPE_PREFIX_ALIEN_HARDWARE}${FREETZ_TYPE_PREFIX%_0?_??}_${FIRMWAREVERSION}${modbaselaborname}-${SUBVERSION}.${FREETZ_TYPE_LANGUAGE}" if [ "$FREETZ_CUSTOM_IMAGE_NAME" == "y" -a ! -z "$FREETZ_USER_DEFINED_COMMENT" ]; then modcustomimagestring=$(echo $FREETZ_USER_DEFINED_COMMENT | sed -e "s/ /_/g" | tr -cd 'a-zA-Z0-9_+-.<->') else modcustomimagestring="" fi if [ "$FREETZ_CUSTOM_IMAGE_NAME" == "y" -a ! -z "${modcustomimagestring}" ]; then if [ "$FREETZ_CUSTOM_IMAGE_NAME_PREFIX" == "y" ]; then modimagenameprefix="${modcustomimagestring}_" modimagenamesuffix="" else modimagenameprefix="" modimagenamesuffix="_${modcustomimagestring}" fi else modimagenameprefix="" modimagenamesuffix="" fi modstring="${modimagenameprefix}${modbaseimagename}${modimagenamesuffix}_$modmakedate" modimage="${modstring}.image" # Create freetz-info echo1 "integrate freetz info file into image" freetz_info_file="$MOD_DIR/filesystem/etc/freetz_info.cfg" echo "export FREETZ_INFO_BOXTYPE='${FREETZ_TYPE_PREFIX_ALIEN_HARDWARE}${FREETZ_TYPE_PREFIX%_0?_??}${FREETZ_TYPE_PREFIX_LABOR_FIRMWARE}'" > "$freetz_info_file" echo "export FREETZ_INFO_FIRMWAREVERSION='${FIRMWAREVERSION}'" >> "$freetz_info_file" echo "export FREETZ_INFO_SUBVERSION='${SUBVERSION}'" >> "$freetz_info_file" echo "export FREETZ_INFO_LANG='${FREETZ_TYPE_LANGUAGE}'" >> "$freetz_info_file" echo "export FREETZ_INFO_MAKEDATE='$modmakedate'" >> "$freetz_info_file" echo "export FREETZ_INFO_IMAGE_NAME='$modimage'" >> "$freetz_info_file" echo "export FREETZ_INFO_COMMENT='${FREETZ_USER_DEFINED_COMMENT}'" >> "$freetz_info_file" externalised_files=$(find build/modified/external/ -type f 2>/dev/null | sed -e '/\.external/d;s,build/modified/external/,,') echo "export FREETZ_INFO_EXTERNAL_FILES='${externalised_files}'" >> "$freetz_info_file" # Pack var.tar (use old tar for compatibility) echo0 "packing var.tar" "$TAR" -C "$VARTAR_MOD_DIR" -cf "$VARTAR_MOD" . || exit 1 [ ! -s "$VARTAR_MOD" ] && error 1 "packing of var.tar failed" [ "$FREETZ_HAS_AVM_UDEV" == "y" ] || \ $MAKEDEVS -d $MAKEDEVS_FILE $FILESYSTEM_MOD_DIR > $MOD_DIR/filesystem.log 2>&1 fi # ------------------------------------------------------------------ # -- Zip file system to tar.gz archive (USB root, maybe NFS root) -- # ------------------------------------------------------------------ if [ "$DO_ZIP" -gt 0 ]; then if [ "$FW_IMAGES_DIR" ]; then zip_name="${FW_IMAGES_DIR}/${modstring}_rootfs.tar.gz" else zip_name="${DIR}/${modstring}_rootfs.tar.gz" fi echo0 "zipping root file system to $zip_name" "$TAR" -C "$FILESYSTEM_MOD_DIR" -czf "$zip_name" . || exit 1 if [ ! -s "$zip_name" ]; then rm -f "$zip_name" error 1 "zipping of root file system failed" fi echo "$zip_name" > "${DIR}/.rootfs_archive" fi # ------------------------- # -- Pack firmware image -- # ------------------------- if [ "$DO_PACK" -gt 0 ]; then # Do we have the tool ? [ ! -x "$MKSQUASHFS" ] && error 1 "cannot find $MKSQUASHFS_TOOL" echo0 "creating filesystem image" echo1 "SquashFS block size: $FREETZ_SQUASHFS_BLOCKSIZE ($(($FREETZ_SQUASHFS_BLOCKSIZE/1024)) kB)" $TOOLS_DIR/$MKSQUASHFS_TOOL $FILESYSTEM_MOD_DIR/* $ABS_BASE_DIR/$CORE_FILESYSTEM_MOD $MKSQUASHFS_OPTIONS -b $FREETZ_SQUASHFS_BLOCKSIZE >> $MOD_DIR/filesystem.log 2>&1 if [ "${FREETZ_HAS_UPDATE_FILESYSTEM_IMAGE}" == "y" ]; then $TOOLS_DIR/$MKSQUASHFS_TOOL $FILESYSTEM_CORE_MOD_DIR/* $ABS_BASE_DIR/$RAW_FILESYSTEM_MOD $MKSQUASHFS_OPTIONS -b $FREETZ_SQUASHFS_BLOCKSIZE >> $MOD_DIR/filesystem.log 2>&1 [ ! -s "$RAW_FILESYSTEM_MOD" ] && error 1 "creation of filesystem failed" let FILESYSTEM_SIZE="$(wc -c < "$RAW_FILESYSTEM_MOD")" [ "$FILESYSTEM_SIZE" -eq 0 ] && error 1 "filesystem image is empty" echo0 "copying kernel image" cp -a "$RAW_KERNEL_MOD" "$KERNEL_MOD" echo0 "copying filesystem image" cp -a "$RAW_FILESYSTEM_MOD" "$FILESYSTEM_MOD" else [ ! -s "$RAW_FILESYSTEM_MOD" ] && error 1 "creation of filesystem failed" touch "$FILESYSTEM_MOD" echo0 "merging kernel image" dd if="$RAW_KERNEL_MOD" of="$KERNEL_MOD" bs=256 conv=sync 2> /dev/null cat "$RAW_FILESYSTEM_MOD" >> "$KERNEL_MOD" [ ! -s "$KERNEL_MOD" ] && error 1 "kernel merging failed" # Check size of kernel image (multiple of 64 kB blocks) if [ -n "$FREETZ_KERNEL_CUSTOM_MTD_SIZE" ]; then let KERNEL_LIMIT="$FREETZ_KERNEL_CUSTOM_MTD_SIZE*64*1024" else KERNEL_LIMIT="$(sed -nr 's/^kernel_size=(.*)/\1/p' ${FIRMWARE_DIR}/var/install)" [ -z "$KERNEL_LIMIT" ] && error 1 "Can't find kernel_size in var/install" fi let KERNEL_SIZE="$(wc -c < "$KERNEL_MOD")" let DIFF="KERNEL_SIZE-KERNEL_LIMIT" echo1 "kernel image size: $KERNEL_SIZE (max: $KERNEL_LIMIT, free: $((-DIFF)))" [ "$KERNEL_SIZE" -eq 0 ] && error 1 "kernel image is empty" if [ "$KERNEL_SIZE" -gt "$KERNEL_LIMIT" ]; then if [ "$FORCE_PACK" -eq 0 -a "$DO_ZIP" -eq 0 ]; then error 1 -b "kernel image is $DIFF bytes too big. See http://freetz.org/wiki/FAQ#Filesystemimagetoobig for details." fi if [ "$FORCE_PACK" -gt 0 -a "$DO_ZIP" -eq 0 ]; then echo0 -b "Use for SDK mode only. See http://wehavemorefun.de/fritzbox/index.php/SDK-Firmware" fi if [ "$FORCE_PACK" -eq 0 -a "$DO_ZIP" -gt 0 ]; then echo0 -b "Use for USBroot or NFSroot mode only." fi fi fi if [ "$FREETZ_VERBOSITY_LEVEL" -ge 1 ]; then if [ "$FREETZ_HAS_AVM_TAM" = "y" -a "${FREETZ_HAS_UPDATE_FILESYSTEM_IMAGE}" != "y" ]; then # Calculate aproximately free space in seconds for the answering machine # 5*64kB sectors needed, see http://freetz.org/ticket/1680#comment:4 FREE_BYTE_JFFS2=$((($KERNEL_LIMIT - $KERNEL_SIZE - 327680))) FREE_MINUTES=$((($FREE_BYTE_JFFS2 / 2017 / 60))) if [ "$FREE_BYTE_JFFS2" -gt 0 ]; then echo "${L1}Aproximately free time for the answering machine: $((($FREE_BYTE_JFFS2 / 2017)))s (${FREE_MINUTES}min $((($FREE_BYTE_JFFS2 / 2017 - $FREE_MINUTES * 60)))s)" else if [ "$FREETZ_REMOVE_JFFS2" != "y" ]; then echo "${L1}WARNING: Not enough free flash space for answering machine!" else echo "${L1}Telephone answering machine will need a usb storage device!" fi fi fi fi # Do we have the tool ? [ ! -x "$TICHKSUM" ] && error 1 "cannot find tool $TICHKSUM_TOOL" # Write checksum "$TICHKSUM" "$KERNEL_MOD" > "${MOD_DIR}/kernelchksum.log" # Consistency check if [ -s "${FIRMWARE_DIR}/${KERNEL_IMAGE}" -a ! -s "${FIRMWARE_MOD_DIR}/${KERNEL_IMAGE}" ] || \ [ ! -s "${FIRMWARE_DIR}/${KERNEL_IMAGE}" -a -s "${FIRMWARE_MOD_DIR}/${KERNEL_IMAGE}" ]; then error 1 "inconsistency comparing size of old and new kernel.image" fi # Last, but not least, include .config and addon/static.pkg into firmware # image for further reference, e.g. user support [ -r "$DOT_CONFIG" ] && cp "$DOT_CONFIG" "$FIRMWARE_MOD_DIR/var" [ -r "$STATIC_ADDON_FILE" ] && cp "$STATIC_ADDON_FILE" "$FIRMWARE_MOD_DIR/var" [ -r "$PACKAGES_LIST_FILE" ] && cp "$PACKAGES_LIST_FILE" "$FIRMWARE_MOD_DIR/var" # Pack firmware image (use old tar for compatibility) if [ "$FW_IMAGES_DIR" ]; then img_name="${FW_IMAGES_DIR}/${modimage}" else img_name="${DIR}/${modimage}" fi echo0 "packing $img_name" "$TAR" -C "$FIRMWARE_MOD_DIR" -cf "$img_name" . || exit 1 if [ ! -s "$img_name" ]; then rm -f "$img_name" error 1 "packing of firmware image failed" fi fi # ---------------------------------------------- # -- Common final actions for pack, zip, copy -- # ---------------------------------------------- if [ "$action_names" ]; then # Pack externalised files if [ "$EXTERNAL_CREATEPAK" == "y" ] && [ -n "$externalised_files" ]; then modexternal="${modimagenameprefix}${modbaseimagename}${modimagenamesuffix}_$modmakedate.external" if [ "$FW_IMAGES_DIR" ]; then modexternal="${FW_IMAGES_DIR}/${modexternal}" else modexternal="${DIR}/${modexternal}" fi echo "packing ${modexternal}" "$TAR" -C "$EXTERNAL_MOD_DIR" -cf "$modexternal" . || exit 1 if [ ! -s "$modexternal" ]; then rm -f "$modexternal" error 1 "packing of external tar failed" fi fi if [ "$FREETZ_REPLACE_SSL_LIBS" == "y" ] && [ "$FREETZ_LIB_libcrypto" == "y" -o "$FREETZ_LIB_libssl" == "y" ]; then echo "Caution: Replacing libcrypto or libssl may cause an unusable image." echo "See http://freetz.org/wiki/FAQ#NachdemFlashenistdasAVM-Webinterfacenichtmehrerreichbar for details." fi [ "$COPY_FS_DIR" ] || echo -e "done.\n" fi [ "$COPY_FS_DIR" ] || echo0 -b "FINISHED" exit 0