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