xref: /rk3399_rockchip-uboot/scripts/fit.sh (revision 2a7051be6cb4eddfbb7c8a7288750ec77adc42f3)
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
9FIT_DIR="fit"
10IMG_UBOOT="uboot.img"
11IMG_BOOT="boot.img"
12ITB_UBOOT="${FIT_DIR}/uboot.itb"
13ITB_BOOT="${FIT_DIR}/boot.itb"
14SIG_BIN="data2sign.bin"
15SIG_UBOOT="${FIT_DIR}/uboot.data2sign"
16SIG_BOOT="${FIT_DIR}/boot.data2sign"
17# offs
18OFFS_NS_UBOOT="0xc00"
19OFFS_S_UBOOT="0xc00"
20OFFS_NS_BOOT="0x800"
21OFFS_S_BOOT="0xc00"
22# file
23CHIP_FILE="arch/arm/lib/.asm-offsets.s.cmd"
24# placeholder address
25FDT_ADDR_PLACEHOLDER="0xffffff00"
26KERNEL_ADDR_PLACEHOLDER="0xffffff01"
27RAMDISK_ADDR_PLACEHOLDER="0xffffff02"
28# tools
29MKIMAGE="./tools/mkimage"
30FIT_UNPACK="./scripts/fit-unpack.sh"
31CHECK_SIGN="./tools/fit_check_sign"
32# key
33KEY_DIR="keys/"
34RSA_PRI_KEY="keys/dev.key"
35RSA_PUB_KEY="keys/dev.crt"
36SIGNATURE_KEY_NODE="/signature/key-dev"
37SPL_DTB="spl/u-boot-spl.dtb"
38UBOOT_DTB="u-boot.dtb"
39# its
40ITS_UBOOT="u-boot.its"
41ITS_BOOT="boot.its"
42ARG_VER_UBOOT="0"
43ARG_VER_BOOT="0"
44
45function help()
46{
47	echo
48	echo "usage:"
49	echo "    $0 [args]"
50	echo
51	echo "args:"
52	echo "    --rollback-index-boot   <decimal integer>"
53	echo "    --rollback-index-uboot  <decimal integer>"
54	echo "    --version-uboot         <decimal integer>"
55	echo "    --version-boot          <decimal integer>"
56	echo "    --ini-trust"
57	echo "    --ini-loader"
58	echo "    --no-check"
59	echo "    --spl-new"
60	echo "    --boot_img"
61	echo "    --args"
62	echo
63}
64
65function arg_check_decimal()
66{
67	if [ -z $1 ]; then
68		help
69		exit 1
70	fi
71
72	decimal=`echo $1 |sed 's/[0-9]//g'`
73	if [ ! -z ${decimal} ]; then
74		echo "ERROR: $1 is not decimal integer"
75		help
76		exit 1
77	fi
78}
79
80function check_its()
81{
82	cat $1 | while read line
83	do
84		file=`echo ${line} | sed -n "/incbin/p" | awk -F '"' '{ printf $2 }' | tr -d ' '`
85		if [ ! -f ${file} ]; then
86			echo "ERROR: No ${file}"
87			exit 1
88		fi
89	done
90}
91
92function validate_arg()
93{
94	case $1 in
95		--no-check|--spl-new|--burn-key-hash)
96			shift=1
97			;;
98		--ini-trust|--ini-loader|--rollback-index-boot|--rollback-index-uboot|--boot_img|--version-uboot|--version-boot)
99			shift=2
100			;;
101		*)
102			shift=0
103			;;
104	esac
105	echo ${shift}
106}
107
108function fit_process_args()
109{
110	if [ $# -eq 0 ]; then
111		help
112		exit 0
113	fi
114
115	while [ $# -gt 0 ]; do
116		case $1 in
117			--args)
118				ARG_VALIDATE=$2
119				shift 2
120				;;
121			--boot_img)     # boot.img
122				ARG_BOOT_IMG=$2
123				shift 2
124				;;
125			--boot_img_dir) # boot.img components directory
126				ARG_BOOT_IMG_DIR=$2
127				shift 2
128				;;
129			--no-check)     # No hostcc fit signature check
130				ARG_NO_CHECK="y"
131				shift 1
132				;;
133			--ini-trust)    # Assign trust ini file
134				ARG_INI_TRUST=$2
135				shift 2
136				;;
137			--ini-loader)   # Assign loader ini file
138				ARG_INI_LOADER=$2
139				shift 2
140				;;
141			--spl-new)      # Use current build u-boot-spl.bin to pack loader
142				ARG_SPL_NEW="y"
143				shift 1
144				;;
145			--rollback-index-boot)
146				ARG_ROLLBACK_IDX_BOOT=$2
147				arg_check_decimal $2
148				shift 2
149				;;
150			--rollback-index-uboot)
151				ARG_ROLLBACK_IDX_UBOOT=$2
152				arg_check_decimal $2
153				shift 2
154				;;
155			--version-uboot)
156				ARG_VER_UBOOT=$2
157				arg_check_decimal $2
158				shift 2
159				;;
160			--version-boot)
161				ARG_VER_BOOT=$2
162				arg_check_decimal $2
163				shift 2
164				;;
165			--burn-key-hash)
166				ARG_BURN_KEY_HASH="y"
167				shift 1
168				;;
169			*)
170				help
171				exit 1
172				;;
173		esac
174	done
175
176	if grep -q '^CONFIG_FIT_SIGNATURE=y' .config ; then
177		ARG_SIGN="y"
178	fi
179}
180
181function fit_raw_compile()
182{
183	# Verified-boot: should rebuild code but don't need to repack images.
184	if [ "${ARG_SIGN}" == "y" ]; then
185		./make.sh --raw-compile
186	fi
187	rm ${FIT_DIR} -rf && mkdir -p ${FIT_DIR}
188}
189
190function fit_gen_uboot_itb()
191{
192	# generate u-boot.its file
193	./make.sh itb ${ARG_INI_TRUST}
194
195	# check existance of file in its
196	check_its ${ITS_UBOOT}
197
198	if [ "${ARG_SIGN}" != "y" ]; then
199		${MKIMAGE} -f ${ITS_UBOOT} -E -p ${OFFS_NS_UBOOT} ${ITB_UBOOT} -v ${ARG_VER_UBOOT}
200		if [ "${ARG_SPL_NEW}" == "y" ]; then
201			./make.sh --spl ${ARG_INI_LOADER}
202			echo "pack loader with new: spl/u-boot-spl.bin"
203		else
204			./make.sh loader ${ARG_INI_LOADER}
205		fi
206	else
207		if [ ! -f ${RSA_PRI_KEY} ]; then
208			echo "ERROR: No ${RSA_PRI_KEY} "
209			exit 1
210		elif [ ! -f ${RSA_PUB_KEY} ]; then
211			echo "ERROR: No ${RSA_PUB_KEY} "
212			exit 1
213		fi
214
215		if ! grep -q '^CONFIG_SPL_FIT_SIGNATURE=y' .config ; then
216			echo "ERROR: CONFIG_SPL_FIT_SIGNATURE is disabled"
217			exit 1
218		fi
219
220		# rollback-index
221		if grep -q '^CONFIG_SPL_FIT_ROLLBACK_PROTECT=y' .config ; then
222			ARG_SPL_ROLLBACK_PROTECT="y"
223			if [ -z ${ARG_ROLLBACK_IDX_UBOOT} ]; then
224				echo "ERROR: No arg \"--rollback-index-uboot <n>\""
225				exit 1
226			fi
227		fi
228
229		if [ "${ARG_SPL_ROLLBACK_PROTECT}" == "y" ]; then
230			VERSION=`grep 'rollback-index' ${ITS_UBOOT} | awk -F '=' '{ printf $2 }' | tr -d ' '`
231			sed -i "s/rollback-index = ${VERSION}/rollback-index = <${ARG_ROLLBACK_IDX_UBOOT}>;/g" ${ITS_UBOOT}
232		fi
233
234		# Generally, boot.img is signed before uboot.img, so the ras key can be found
235		# in u-boot.dtb. If not found, let's insert rsa key anyway.
236		if ! fdtget -l ${UBOOT_DTB} /signature >/dev/null 2>&1 ; then
237			${MKIMAGE} -f ${ITS_UBOOT} -k ${KEY_DIR} -K ${UBOOT_DTB} -E -p ${OFFS_S_UBOOT} -r ${ITB_UBOOT} -v ${ARG_VER_UBOOT}
238			echo "## Adding RSA public key into ${UBOOT_DTB}"
239		fi
240
241		# Pack
242		${MKIMAGE} -f ${ITS_UBOOT} -k ${KEY_DIR} -K ${SPL_DTB} -E -p ${OFFS_S_UBOOT} -r ${ITB_UBOOT} -v ${ARG_VER_UBOOT}
243		mv ${SIG_BIN} ${SIG_UBOOT}
244
245		# burn-key-hash
246		if [ "${ARG_BURN_KEY_HASH}" == "y" ]; then
247			fdtput -tx ${SPL_DTB} ${SIGNATURE_KEY_NODE} burn-key-hash 0x1
248		fi
249
250		# rollback-index read back check
251		if [ "${ARG_SPL_ROLLBACK_PROTECT}" == "y" ]; then
252			VERSION=`fdtget -ti ${ITB_UBOOT} /configurations/conf rollback-index`
253			if [ "${VERSION}" != "${ARG_ROLLBACK_IDX_UBOOT}" ]; then
254				echo "ERROR: Failed to set rollback-index for ${ITB_UBOOT}";
255				exit 1
256			fi
257		fi
258
259		# burn-key-hash read back check
260		if [ "${ARG_BURN_KEY_HASH}" == "y" ]; then
261			if [ "`fdtget -ti ${SPL_DTB} ${SIGNATURE_KEY_NODE} burn-key-hash`" != "1" ]; then
262				echo "ERROR: Failed to set burn-key-hash for ${SPL_DTB}";
263				exit 1
264			fi
265		fi
266
267		# host check signature
268		if [ "${ARG_NO_CHECK}" != "y" ]; then
269			if [ "${ARG_SPL_NEW}" == "y" ]; then
270				 ${CHECK_SIGN} -f ${ITB_UBOOT} -k ${SPL_DTB} -s
271			else
272				spl_file="../rkbin/"`sed -n "/FlashBoot=/s/FlashBoot=//p" ${ARG_INI_LOADER}  |tr -d '\r'`
273				offs=`fdtdump -s ${spl_file} | head -1 | awk -F ":" '{ print $2 }' | sed "s/ found fdt at offset //g" | tr -d " "`
274				if [ -z ${offs}  ]; then
275					echo "ERROR: invalid ${spl_file} , unable to find fdt blob"
276				fi
277				offs=`printf %d ${offs} ` # hex -> dec
278				dd if=${spl_file} of=spl/u-boot-spl-old.dtb bs=${offs} skip=1 >/dev/null 2>&1
279				${CHECK_SIGN} -f ${ITB_UBOOT} -k spl/u-boot-spl-old.dtb -s
280			fi
281		fi
282
283		# minimize u-boot-spl.dtb: clear as 0 but not remove property.
284		if grep -q '^CONFIG_SPL_FIT_HW_CRYPTO=y' .config ; then
285			fdtput -tx ${SPL_DTB} ${SIGNATURE_KEY_NODE} rsa,r-squared 0x0
286			if grep -q '^CONFIG_SPL_ROCKCHIP_CRYPTO_V1=y' .config ; then
287				fdtput -tx ${SPL_DTB} ${SIGNATURE_KEY_NODE} rsa,np 0x0
288				fdtput -r ${SPL_DTB} ${SIGNATURE_KEY_NODE}/hash@np
289			else
290				fdtput -tx ${SPL_DTB} ${SIGNATURE_KEY_NODE} rsa,c 0x0
291				fdtput -r ${SPL_DTB} ${SIGNATURE_KEY_NODE}/hash@c
292			fi
293		else
294			fdtput -tx ${SPL_DTB} ${SIGNATURE_KEY_NODE} rsa,c 0x0
295			fdtput -tx ${SPL_DTB} ${SIGNATURE_KEY_NODE} rsa,np 0x0
296			fdtput -tx ${SPL_DTB} ${SIGNATURE_KEY_NODE} rsa,exponent-BN 0x0
297			fdtput -r ${SPL_DTB} ${SIGNATURE_KEY_NODE}/hash@c
298			fdtput -r ${SPL_DTB} ${SIGNATURE_KEY_NODE}/hash@np
299		fi
300
301		# repack spl
302		rm -f *_loader_*.bin
303		if [ "${ARG_SPL_NEW}" == "y" ]; then
304			cat spl/u-boot-spl-nodtb.bin > spl/u-boot-spl.bin
305			if ! grep -q '^CONFIG_SPL_SEPARATE_BSS=y' .config ; then
306				cat spl/u-boot-spl-pad.bin >> spl/u-boot-spl.bin
307			fi
308			cat ${SPL_DTB} >> spl/u-boot-spl.bin
309
310			./make.sh --spl ${ARG_INI_LOADER}
311			echo "## pack loader with new: spl/u-boot-spl.bin"
312		else
313			./make.sh loader ${ARG_INI_LOADER}
314		fi
315
316		if [ "${ARG_BURN_KEY_HASH}" == "y" ]; then
317			echo "## ${SPL_DTB}: burn-key-hash=1"
318		fi
319	fi
320
321	rm -f u-boot.itb u-boot.img u-boot-dtb.img
322	mv ${ITS_UBOOT} ${FIT_DIR}
323}
324
325function fit_gen_boot_itb()
326{
327	if [ ! -z ${ARG_BOOT_IMG} ]; then
328		${FIT_UNPACK} -f ${ARG_BOOT_IMG} -o ${FIT_DIR}/unpack
329		ITS_BOOT="${FIT_DIR}/unpack/image.its"
330	else
331		compression=`awk -F"," '/COMPRESSION=/  { printf $1 }' ${ARG_INI_TRUST} | tr -d ' ' | cut -c 13-`
332		if [ -z "${compression}" ]; then
333			compression="none"
334		fi
335		./arch/arm/mach-rockchip/make_fit_boot.sh -c ${compression} > ${ITS_BOOT}
336		check_its ${ITS_BOOT}
337	fi
338
339	if [ "${ARG_SIGN}" != "y" ]; then
340		${MKIMAGE} -f ${ITS_BOOT} -E -p ${OFFS_NS_BOOT} ${ITB_BOOT} -v ${ARG_VER_BOOT}
341	else
342		if [ ! -f ${RSA_PRI_KEY}  ]; then
343			echo "ERROR: No ${RSA_PRI_KEY}"
344			exit 1
345		elif [ ! -f ${RSA_PUB_KEY}  ]; then
346			echo "ERROR: No ${RSA_PUB_KEY}"
347			exit 1
348		fi
349
350		if ! grep -q '^CONFIG_FIT_SIGNATURE=y' .config ; then
351			echo "ERROR: CONFIG_FIT_SIGNATURE is disabled"
352			exit 1
353		fi
354
355		if grep -q '^CONFIG_FIT_ROLLBACK_PROTECT=y' .config ; then
356			ARG_ROLLBACK_PROTECT="y"
357			if [ -z ${ARG_ROLLBACK_IDX_BOOT} ]; then
358				echo "ERROR: No arg \"--rollback-index-boot <n>\""
359				exit 1
360			fi
361		fi
362
363		# fixup
364		COMMON_FILE=`sed -n "/_common.h/p" ${CHIP_FILE} | awk '{ print $1 }'`
365		FDT_ADDR_R=`awk /fdt_addr_r/         ${COMMON_FILE} | awk -F '=' '{ print $2 }' | awk -F '\\' '{ print $1 }'`
366		KERNEL_ADDR_R=`awk /kernel_addr_r/   ${COMMON_FILE} | awk -F '=' '{ print $2 }' | awk -F '\\' '{ print $1 }'`
367		RMADISK_ADDR_R=`awk /ramdisk_addr_r/ ${COMMON_FILE} | awk -F '=' '{ print $2 }' | awk -F '\\' '{ print $1 }'`
368		sed -i "s/${FDT_ADDR_PLACEHOLDER}/${FDT_ADDR_R}/g"         ${ITS_BOOT}
369		sed -i "s/${KERNEL_ADDR_PLACEHOLDER}/${KERNEL_ADDR_R}/g"   ${ITS_BOOT}
370		sed -i "s/${RAMDISK_ADDR_PLACEHOLDER}/${RMADISK_ADDR_R}/g" ${ITS_BOOT}
371		if grep -q '^CONFIG_ARM64=y' .config ; then
372			sed -i 's/arch = "arm";/arch = "arm64";/g' ${ITS_BOOT}
373		fi
374
375		if [ "${ARG_ROLLBACK_PROTECT}" == "y" ]; then
376			VERSION=`grep 'rollback-index' ${ITS_BOOT} | awk -F '=' '{ printf $2 }' | tr -d ' '`
377			sed -i "s/rollback-index = ${VERSION}/rollback-index = <${ARG_ROLLBACK_IDX_BOOT}>;/g" ${ITS_BOOT}
378		fi
379
380		${MKIMAGE} -f ${ITS_BOOT} -k ${KEY_DIR} -K ${UBOOT_DTB} -E -p ${OFFS_S_BOOT} -r ${ITB_BOOT} -v ${ARG_VER_BOOT}
381		mv ${SIG_BIN} ${SIG_BOOT}
382
383		# rollback-index read back check
384		if [ "${ARG_ROLLBACK_PROTECT}" == "y" ]; then
385			VERSION=`fdtget -ti ${ITB_BOOT} /configurations/conf rollback-index`
386			if [ "${VERSION}" != "${ARG_ROLLBACK_IDX_BOOT}" ]; then
387				echo "ERROR: Failed to set rollback-index for ${ITB_BOOT}";
388				exit 1
389			fi
390		fi
391
392		# host check signature
393		if [ "${ARG_NO_CHECK}" != "y" ]; then
394			 ${CHECK_SIGN} -f ${ITB_BOOT} -k ${UBOOT_DTB}
395		fi
396
397		# minimize u-boot.dtb: clearn as 0 but not remove property.
398		if grep -q '^CONFIG_FIT_HW_CRYPTO=y' .config ; then
399			fdtput -tx ${UBOOT_DTB} ${SIGNATURE_KEY_NODE} rsa,r-squared 0x0
400			if grep -q '^CONFIG_ROCKCHIP_CRYPTO_V1=y' .config ; then
401				fdtput -tx ${UBOOT_DTB} ${SIGNATURE_KEY_NODE} rsa,np 0x0
402			else
403				fdtput -tx ${UBOOT_DTB} ${SIGNATURE_KEY_NODE} rsa,c 0x0
404			fi
405		else
406			fdtput -tx ${UBOOT_DTB} ${SIGNATURE_KEY_NODE} rsa,c 0x0
407			fdtput -tx ${UBOOT_DTB} ${SIGNATURE_KEY_NODE} rsa,np 0x0
408			fdtput -tx ${UBOOT_DTB} ${SIGNATURE_KEY_NODE} rsa,exponent-BN 0x0
409		fi
410		fdtput -r ${UBOOT_DTB} ${SIGNATURE_KEY_NODE}/hash@c
411		fdtput -r ${UBOOT_DTB} ${SIGNATURE_KEY_NODE}/hash@np
412	fi
413
414	mv ${ITS_BOOT} ${FIT_DIR}
415}
416
417function fit_gen_uboot_img()
418{
419	ITB=$1
420
421	if [ -z ${ITB} ]; then
422		ITB=${ITB_UBOOT}
423	fi
424
425	ITB_MAX_NUM=`sed -n "/SPL_FIT_IMAGE_MULTIPLE/p" .config | awk -F "=" '{ print $2 }'`
426	ITB_MAX_KB=`sed  -n "/SPL_FIT_IMAGE_KB/p" .config | awk -F "=" '{ print $2 }'`
427	ITB_MAX_BS=$((ITB_MAX_KB*1024))
428	ITB_BS=`ls -l ${ITB} | awk '{ print $5 }'`
429
430	if [ ${ITB_BS} -gt ${ITB_MAX_BS} ]; then
431		echo "ERROR: pack ${IMG_UBOOT} failed! ${ITB} actual: ${ITB_BS} bytes, max limit: ${ITB_MAX_BS} bytes"
432		exit 1
433	fi
434
435	rm -f ${IMG_UBOOT}
436	for ((i = 0; i < ${ITB_MAX_NUM}; i++));
437	do
438		cat ${ITB} >> ${IMG_UBOOT}
439		truncate -s %${ITB_MAX_KB}K ${IMG_UBOOT}
440	done
441}
442
443function fit_gen_boot_img()
444{
445	ITB=$1
446
447	if [ -z ${ITB} ]; then
448		ITB=${ITB_BOOT}
449	fi
450
451	if [ "${ITB}" != "${IMG_BOOT}" ]; then
452		cp ${ITB} ${IMG_BOOT} -f
453	fi
454}
455
456function fit_msg_uboot()
457{
458	if [ "${ARG_SIGN}" != "y" ]; then
459		MSG_SIGN="no-signed"
460	else
461		MSG_SIGN="signed"
462	fi
463
464	VERSION=`fdtget -ti ${ITB_UBOOT} / version`
465	if [ "${VERSION}" != "" ]; then
466		MSG_VER=", version=${VERSION}"
467	fi
468
469	if [ "${ARG_SPL_ROLLBACK_PROTECT}" == "y" ]; then
470		echo "Image(${MSG_SIGN}${MSG_VER}, rollback-index=${ARG_ROLLBACK_IDX_UBOOT}):  ${IMG_UBOOT} (with uboot, trust...) is ready"
471	else
472		echo "Image(${MSG_SIGN}${MSG_VER}):  ${IMG_UBOOT} (FIT with uboot, trust...) is ready"
473	fi
474}
475
476function fit_msg_boot()
477{
478	if [ "${ARG_SIGN}" != "y" ]; then
479		MSG_SIGN="no-signed"
480	else
481		MSG_SIGN="signed"
482	fi
483
484	VERSION=`fdtget -ti ${ITB_BOOT} / version`
485	if [ "${VERSION}" != "" ]; then
486		MSG_VER=", version=${VERSION}"
487	fi
488
489	if [ "${ARG_ROLLBACK_PROTECT}" == "y" ]; then
490		echo "Image(${MSG_SIGN}${MSG_VER}, rollback-index=${ARG_ROLLBACK_IDX_BOOT}):  ${IMG_BOOT} is ready"
491	else
492		echo "Image(${MSG_SIGN}${MSG_VER}):  ${IMG_BOOT} (FIT with kernel, fdt, resource...) is ready"
493	fi
494}
495
496function fit_msg_loader()
497{
498	LOADER=`ls *loader*.bin`
499	echo "Image(no-signed):  ${LOADER} (with spl, ddr, usbplug) is ready"
500}
501
502function fit_generate_uboot()
503{
504	fit_raw_compile
505	fit_gen_uboot_itb
506	fit_gen_uboot_img
507	echo
508	fit_msg_uboot
509}
510
511function fit_generate_uboot_boot()
512{
513	fit_raw_compile
514	fit_gen_boot_itb
515	fit_gen_boot_img
516	fit_gen_uboot_itb
517	fit_gen_uboot_img
518	echo
519
520	fit_msg_uboot
521	fit_msg_boot
522	fit_msg_loader
523	echo
524}
525
526fit_process_args $*
527if [ ! -z "${ARG_VALIDATE}" ]; then
528	validate_arg ${ARG_VALIDATE}
529elif [ ! -z "${ARG_BOOT_IMG}" -o ! -z "${ARG_BOOT_IMG_DIR}" ]; then
530	fit_generate_uboot_boot
531else
532	fit_generate_uboot
533fi
534
535