xref: /rk3399_rockchip-uboot/scripts/fit-unpack.sh (revision 79283ba6e7dc3f688061585818d9476fc95e4067)
175323eb8SJoseph Chen#!/bin/bash
275323eb8SJoseph Chen#
375323eb8SJoseph Chen# Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd
475323eb8SJoseph Chen#
575323eb8SJoseph Chen# SPDX-License-Identifier: GPL-2.0
675323eb8SJoseph Chen#
71ae3dd15SJoseph Chenset -e
875323eb8SJoseph Chen
975323eb8SJoseph Chenfunction usage()
1075323eb8SJoseph Chen{
1175323eb8SJoseph Chen	echo
1275323eb8SJoseph Chen	echo "usage:"
131ff581bbSJoseph Chen	echo "    $0 -f [fit/itb] -o [out]"
1475323eb8SJoseph Chen	echo
1575323eb8SJoseph Chen}
1675323eb8SJoseph Chen
1775323eb8SJoseph Chenfunction args_process()
1875323eb8SJoseph Chen{
191ae3dd15SJoseph Chen	if [ $# -ne 4 -a $# -ne 2 ]; then
2075323eb8SJoseph Chen		usage
2175323eb8SJoseph Chen		exit 1
2275323eb8SJoseph Chen	fi
2375323eb8SJoseph Chen
2475323eb8SJoseph Chen	while [ $# -gt 0 ]; do
2575323eb8SJoseph Chen		case $1 in
2675323eb8SJoseph Chen			-f)
271ff581bbSJoseph Chen				ITB=$2
2875323eb8SJoseph Chen				shift 2
2975323eb8SJoseph Chen				;;
3075323eb8SJoseph Chen			-o)
311ff581bbSJoseph Chen				OUT=$2
3275323eb8SJoseph Chen				shift 2
3375323eb8SJoseph Chen				;;
3475323eb8SJoseph Chen			*)
3575323eb8SJoseph Chen				usage
3675323eb8SJoseph Chen				exit 1
3775323eb8SJoseph Chen				;;
3875323eb8SJoseph Chen		esac
3975323eb8SJoseph Chen	done
4075323eb8SJoseph Chen
411ff581bbSJoseph Chen	if [ ! -f ${ITB} ]; then
421ff581bbSJoseph Chen		echo "ERROR: No ${ITB}"
4375323eb8SJoseph Chen		exit 1
44e156df43SJoseph Chen	elif ! file ${ITB} | grep 'Device Tree Blob' ; then
45e156df43SJoseph Chen		echo "ERROR: ${ITB} is not FIT image"
46e156df43SJoseph Chen		exit 1
4775323eb8SJoseph Chen	fi
4875323eb8SJoseph Chen
491ff581bbSJoseph Chen	if [ -z ${OUT} ]; then
501ff581bbSJoseph Chen		OUT="out"
5175323eb8SJoseph Chen	fi
5275323eb8SJoseph Chen}
5375323eb8SJoseph Chen
541ff581bbSJoseph Chenunpack_itb()
5575323eb8SJoseph Chen{
561ff581bbSJoseph Chen	mkdir -p ${OUT}
571ff581bbSJoseph Chen	echo "Unpack to directory ${OUT}:"
581ff581bbSJoseph Chen
591ff581bbSJoseph Chen	for NAME in `fdtget -l ${ITB} /images`
6075323eb8SJoseph Chen	do
611ff581bbSJoseph Chen		# generate ITB
621ff581bbSJoseph Chen		NODE="/images/${NAME}"
631ff581bbSJoseph Chen		OFFS=`fdtget -ti ${ITB} ${NODE} data-position`
641ff581bbSJoseph Chen		SIZE=`fdtget -ti ${ITB} ${NODE} data-size`
651ff581bbSJoseph Chen		if [ -z ${OFFS} ]; then
661ae3dd15SJoseph Chen			continue;
6775323eb8SJoseph Chen		fi
681ae3dd15SJoseph Chen
691ff581bbSJoseph Chen		if [ ${SIZE} -ne 0 ]; then
701ff581bbSJoseph Chen			dd if=${ITB} of=${OUT}/${NAME} bs=${SIZE} count=1 skip=${OFFS} iflag=skip_bytes >/dev/null 2>&1
711ae3dd15SJoseph Chen		else
721ff581bbSJoseph Chen			touch ${OUT}/${NAME}
731ae3dd15SJoseph Chen		fi
740fb435faSJoseph Chen
750fb435faSJoseph Chen		# hash verify
761ff581bbSJoseph Chen		ALGO=`fdtget -ts ${ITB} ${NODE}/hash algo`
771ff581bbSJoseph Chen		if [ -z ${ALGO} ]; then
781ff581bbSJoseph Chen			printf "    %-20s: %d bytes" ${NAME} ${SIZE}
791ff581bbSJoseph Chen		else
801ff581bbSJoseph Chen			VALUE=`fdtget -tx ${ITB} ${NODE}/hash value`
811ff581bbSJoseph Chen			VALUE=`echo " "${VALUE} | sed "s/ / 0x/g"`
821ff581bbSJoseph Chen			CSUM=`"${ALGO}"sum ${OUT}/${NAME} | awk '{ print $1}'`
830fb435faSJoseph Chen
841ff581bbSJoseph Chen			HASH=""
850fb435faSJoseph Chen			for((i=1;;i++));
860fb435faSJoseph Chen			do
871ff581bbSJoseph Chen				HEX=`echo ${VALUE} | awk -v idx=$i '{ print $idx }'`
881ff581bbSJoseph Chen				if [ -z ${HEX} ]; then
890fb435faSJoseph Chen					break;
900fb435faSJoseph Chen				fi
910fb435faSJoseph Chen
921ff581bbSJoseph Chen				HEX=`printf "%08x" ${HEX}`
931ff581bbSJoseph Chen				HASH="${HASH}${HEX}"
940fb435faSJoseph Chen			done
950fb435faSJoseph Chen
961ff581bbSJoseph Chen			printf "  %-20s: %d bytes... %s" ${NAME} ${SIZE} ${ALGO}
971ff581bbSJoseph Chen			if [ "${CSUM}" == "${HASH}" -o ${SIZE} -eq 0 ]; then
980fb435faSJoseph Chen				echo "+"
990fb435faSJoseph Chen			else
1000fb435faSJoseph Chen				echo "-"
1010fb435faSJoseph Chen			fi
1021ff581bbSJoseph Chen		fi
1031ae3dd15SJoseph Chen	done
10475323eb8SJoseph Chen	echo
10575323eb8SJoseph Chen}
10675323eb8SJoseph Chen
107436376efSJoseph Chenfunction gen_its()
108436376efSJoseph Chen{
1091ff581bbSJoseph Chen	ITS=${OUT}/image.its
1101ff581bbSJoseph Chen	TMP_ITB=${OUT}/image.tmp
111436376efSJoseph Chen
112436376efSJoseph Chen	# add placeholder
1131ff581bbSJoseph Chen	cp -a ${ITB} ${TMP_ITB}
11410db6801SJoseph Chen
11510db6801SJoseph Chen	# data and digest value
1161ff581bbSJoseph Chen	for NAME in `fdtget -l ${ITB} /images`; do
11710db6801SJoseph Chen		COMPRESSION=`fdtget -ts ${ITB} /images/${NAME} compression`
118bc02f36cSJoseph Chen		if [ "${COMPRESSION}" == "gzip" ] && fdtget -l "${TMP_ITB}" /images/${NAME}/digest >/dev/null 2>&1; then
11910db6801SJoseph Chen			fdtput -t s ${TMP_ITB} /images/${NAME} data "/INCBIN/(${NAME}.gz)"
12010db6801SJoseph Chen
12110db6801SJoseph Chen			mv ${OUT}/${NAME} ${OUT}/${NAME}.gz
12210db6801SJoseph Chen			gzip -dk ${OUT}/${NAME}.gz
12310db6801SJoseph Chen			openssl dgst -sha256 -binary -out ${OUT}/${NAME}.digest ${OUT}/${NAME}
12410db6801SJoseph Chen			fdtput -t s ${TMP_ITB} /images/${NAME}/digest digest "/INCBIN/(${NAME}.digest)"
125bc02f36cSJoseph Chen		elif [ "${COMPRESSION}" == "lzma" ] && fdtget -l "${TMP_ITB}" /images/${NAME}/digest >/dev/null 2>&1; then
12610db6801SJoseph Chen			fdtput -t s ${TMP_ITB} /images/${NAME} data "/INCBIN/(${NAME}.lzma)"
12710db6801SJoseph Chen
12810db6801SJoseph Chen			SIZE=`ls -l ${OUT}/${NAME} | awk '{ print $5 }'`
12910db6801SJoseph Chen			SIZE=$(echo "obase=10;$(($SIZE-4))"|bc)
13010db6801SJoseph Chen			cp ${OUT}/${NAME} ${OUT}/${NAME}.lzma.bak
13110db6801SJoseph Chen			dd if=${OUT}/${NAME} of=${OUT}/${NAME}.lzma bs=${SIZE} count=1 >/dev/null 2>&1
13210db6801SJoseph Chen			lzma -df ${OUT}/${NAME}.lzma
13310db6801SJoseph Chen			openssl dgst -sha256 -binary -out ${OUT}/${NAME}.digest ${OUT}/${NAME}
13410db6801SJoseph Chen			mv ${OUT}/${NAME}.lzma.bak ${OUT}/${NAME}.lzma
13510db6801SJoseph Chen			fdtput -t s ${TMP_ITB} /images/${NAME}/digest digest "/INCBIN/(${NAME}.digest)"
13610db6801SJoseph Chen		else
1371ff581bbSJoseph Chen			fdtput -t s ${TMP_ITB} /images/${NAME} data "/INCBIN/(${NAME})"
13810db6801SJoseph Chen		fi
139436376efSJoseph Chen	done
14010db6801SJoseph Chen
141*79283ba6SXuhui Lin	DTC=$(find . -type f -name "dtc")
142*79283ba6SXuhui Lin	if [ -z ${DTC} ]; then
143*79283ba6SXuhui Lin		echo "ERROR: No DTC tool"
144*79283ba6SXuhui Lin		exit 1
145*79283ba6SXuhui Lin	fi
146*79283ba6SXuhui Lin	${DTC} -I dtb -O dts ${TMP_ITB} -o ${ITS}
147*79283ba6SXuhui Lin
1481ff581bbSJoseph Chen	rm -f ${TMP_ITB}
1491ff581bbSJoseph Chen
1501ff581bbSJoseph Chen	# fixup placeholder: data = "/INCBIN/(...)"; -> data = /incbin/("...");
1511ff581bbSJoseph Chen	sed -i "s/\"\/INCBIN\/(\(.*\))\"/\/incbin\/(\"\1\")/" ${ITS}
1521ff581bbSJoseph Chen
1531ff581bbSJoseph Chen	# remove
1541ff581bbSJoseph Chen	sed -i "/memreserve/d"		${ITS}
1551ff581bbSJoseph Chen	sed -i "/timestamp/d"		${ITS}
1561ff581bbSJoseph Chen	sed -i "/data-size/d"		${ITS}
1571ff581bbSJoseph Chen	sed -i "/data-position/d"	${ITS}
1581ff581bbSJoseph Chen	sed -i "/value/d"		${ITS}
1591ff581bbSJoseph Chen	sed -i "/hashed-strings/d"	${ITS}
1601ff581bbSJoseph Chen	sed -i "/hashed-nodes/d"	${ITS}
1611ff581bbSJoseph Chen	sed -i "/signer-version/d"	${ITS}
1621ff581bbSJoseph Chen	sed -i "/signer-name/d"		${ITS}
16310db6801SJoseph Chen	sed -i "/version/d"		${ITS}
16410db6801SJoseph Chen	sed -i "/totalsize/d"		${ITS}
16510db6801SJoseph Chen	sed -i "s/digest =/value =/g"	${ITS}
166436376efSJoseph Chen}
167436376efSJoseph Chen
16875323eb8SJoseph Chenargs_process $*
1691ff581bbSJoseph Chenunpack_itb
170436376efSJoseph Chengen_its
1710fb435faSJoseph Chen
172