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