1#!/bin/bash 2# 3# Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd 4# 5# SPDX-License-Identifier: GPL-2.0 6# 7set -e 8 9function usage() 10{ 11 echo 12 echo "usage:" 13 echo " $0 -f [fit/itb] -o [out]" 14 echo 15} 16 17function args_process() 18{ 19 if [ $# -ne 4 -a $# -ne 2 ]; then 20 usage 21 exit 1 22 fi 23 24 while [ $# -gt 0 ]; do 25 case $1 in 26 -f) 27 ITB=$2 28 shift 2 29 ;; 30 -o) 31 OUT=$2 32 shift 2 33 ;; 34 *) 35 usage 36 exit 1 37 ;; 38 esac 39 done 40 41 if [ ! -f ${ITB} ]; then 42 echo "ERROR: No ${ITB}" 43 exit 1 44 elif ! file ${ITB} | grep 'Device Tree Blob' ; then 45 echo "ERROR: ${ITB} is not FIT image" 46 exit 1 47 fi 48 49 if [ -z ${OUT} ]; then 50 OUT="out" 51 fi 52} 53 54unpack_itb() 55{ 56 mkdir -p ${OUT} 57 echo "Unpack to directory ${OUT}:" 58 59 for NAME in `fdtget -l ${ITB} /images` 60 do 61 # generate ITB 62 NODE="/images/${NAME}" 63 OFFS=`fdtget -ti ${ITB} ${NODE} data-position` 64 SIZE=`fdtget -ti ${ITB} ${NODE} data-size` 65 if [ -z ${OFFS} ]; then 66 continue; 67 fi 68 69 if [ ${SIZE} -ne 0 ]; then 70 dd if=${ITB} of=${OUT}/${NAME} bs=${SIZE} count=1 skip=${OFFS} iflag=skip_bytes >/dev/null 2>&1 71 else 72 touch ${OUT}/${NAME} 73 fi 74 75 # hash verify 76 ALGO=`fdtget -ts ${ITB} ${NODE}/hash algo` 77 if [ -z ${ALGO} ]; then 78 printf " %-20s: %d bytes" ${NAME} ${SIZE} 79 else 80 VALUE=`fdtget -tx ${ITB} ${NODE}/hash value` 81 VALUE=`echo " "${VALUE} | sed "s/ / 0x/g"` 82 CSUM=`"${ALGO}"sum ${OUT}/${NAME} | awk '{ print $1}'` 83 84 HASH="" 85 for((i=1;;i++)); 86 do 87 HEX=`echo ${VALUE} | awk -v idx=$i '{ print $idx }'` 88 if [ -z ${HEX} ]; then 89 break; 90 fi 91 92 HEX=`printf "%08x" ${HEX}` 93 HASH="${HASH}${HEX}" 94 done 95 96 printf " %-20s: %d bytes... %s" ${NAME} ${SIZE} ${ALGO} 97 if [ "${CSUM}" == "${HASH}" -o ${SIZE} -eq 0 ]; then 98 echo "+" 99 else 100 echo "-" 101 fi 102 fi 103 done 104 echo 105} 106 107function gen_its() 108{ 109 ITS=${OUT}/image.its 110 TMP_ITB=${OUT}/image.tmp 111 112 # add placeholder 113 cp -a ${ITB} ${TMP_ITB} 114 115 # data and digest value 116 for NAME in `fdtget -l ${ITB} /images`; do 117 COMPRESSION=`fdtget -ts ${ITB} /images/${NAME} compression` 118 if [ "${COMPRESSION}" == "gzip" ] && fdtget -l "${TMP_ITB}" /images/${NAME}/digest >/dev/null 2>&1; then 119 fdtput -t s ${TMP_ITB} /images/${NAME} data "/INCBIN/(${NAME}.gz)" 120 121 mv ${OUT}/${NAME} ${OUT}/${NAME}.gz 122 gzip -dk ${OUT}/${NAME}.gz 123 openssl dgst -sha256 -binary -out ${OUT}/${NAME}.digest ${OUT}/${NAME} 124 fdtput -t s ${TMP_ITB} /images/${NAME}/digest digest "/INCBIN/(${NAME}.digest)" 125 elif [ "${COMPRESSION}" == "lzma" ] && fdtget -l "${TMP_ITB}" /images/${NAME}/digest >/dev/null 2>&1; then 126 fdtput -t s ${TMP_ITB} /images/${NAME} data "/INCBIN/(${NAME}.lzma)" 127 128 SIZE=`ls -l ${OUT}/${NAME} | awk '{ print $5 }'` 129 SIZE=$(echo "obase=10;$(($SIZE-4))"|bc) 130 cp ${OUT}/${NAME} ${OUT}/${NAME}.lzma.bak 131 dd if=${OUT}/${NAME} of=${OUT}/${NAME}.lzma bs=${SIZE} count=1 >/dev/null 2>&1 132 lzma -df ${OUT}/${NAME}.lzma 133 openssl dgst -sha256 -binary -out ${OUT}/${NAME}.digest ${OUT}/${NAME} 134 mv ${OUT}/${NAME}.lzma.bak ${OUT}/${NAME}.lzma 135 fdtput -t s ${TMP_ITB} /images/${NAME}/digest digest "/INCBIN/(${NAME}.digest)" 136 else 137 fdtput -t s ${TMP_ITB} /images/${NAME} data "/INCBIN/(${NAME})" 138 fi 139 done 140 141 dtc -I dtb -O dts ${TMP_ITB} -o ${ITS} 142 rm -f ${TMP_ITB} 143 144 # fixup placeholder: data = "/INCBIN/(...)"; -> data = /incbin/("..."); 145 sed -i "s/\"\/INCBIN\/(\(.*\))\"/\/incbin\/(\"\1\")/" ${ITS} 146 147 # remove 148 sed -i "/memreserve/d" ${ITS} 149 sed -i "/timestamp/d" ${ITS} 150 sed -i "/data-size/d" ${ITS} 151 sed -i "/data-position/d" ${ITS} 152 sed -i "/value/d" ${ITS} 153 sed -i "/hashed-strings/d" ${ITS} 154 sed -i "/hashed-nodes/d" ${ITS} 155 sed -i "/signer-version/d" ${ITS} 156 sed -i "/signer-name/d" ${ITS} 157 sed -i "/version/d" ${ITS} 158 sed -i "/totalsize/d" ${ITS} 159 sed -i "s/digest =/value =/g" ${ITS} 160} 161 162args_process $* 163unpack_itb 164gen_its 165 166