avs_mtk_voice/meta/meta-mediatek/classes/lk-image.bbclass

307 lines
9.7 KiB
Plaintext
Raw Normal View History

2022-05-13 08:02:31 +00:00
python __anonymous () {
depends = d.getVar("DEPENDS", True)
depends = "%s u-boot-mkimage-native dtc-native" % depends
d.setVar("DEPENDS", depends)
}
# Emit fit header
# input param:
# $1: fit its
fitimage_emit_fit_header() {
cat << EOF >> $1
/dts-v1/;
/ {
description = "bl";
#address-cells = <1>;
EOF
}
# Emit the fitimage image section
# input param:
# $1: fit its
# $2: path to padding binary
# $3: path to lk binary
# $4: lk load address
# $5: lk entry address
# $6: hash algorithm
fitimage_emit_fit_image_section() {
cat << EOF >> $1
images {
bl@1 {
description = "bl";
padding = /incbin/("${2}");
data = /incbin/("${3}");
type = "kernel";
compression = "none";
load = <${4}>;
entry = <${5}>;
hash@1 {
algo = "${6}";
};
};
};
EOF
}
# Emit fitimage configuration section
# input param:
# $1: fit its
# $2: hash algorithm
# $3: rsa algorithm
# $4: key name hint
fitimage_emit_fit_conf_section() {
cat << EOF >> $1
configurations {
default = "conf@1";
conf@1 {
description = "bl";
kernel = "bl@1";
signature@1 {
algo = "${2},${3}";
key-name-hint = "${4}";
};
};
};
EOF
}
# Emit fitimage fit end
# input param:
# $1: fit its
fitimage_emit_fit_end() {
cat << EOF >> $1
};
EOF
}
# get_fit_data_offset: get data offset from fit image
# input param:
# $1: fit image
get_fit_data_offset() {
FIT_IMAGE=$1
TMPF=$(mktemp ${WORKDIR}/dump-fit-img.XXXXXX)
# dump fit image
fdtdump -d ${FIT_IMAGE} > ${TMPF}
# get props
LINE=$(grep -n '^ *data' ${TMPF} | grep -o '^[0-9]*')
LINE=`expr ${LINE} - 1`
ADDR=$(grep -n "^// [[:xdigit:]]*: value" ${TMPF} | grep "^${LINE}://" | \
grep -o " [[:xdigit:]]*" | grep -o "[[:xdigit:]]*")
# remove temp files
rm -f ${TMPF}
echo ${ADDR}
}
# check_fit_image: check fit image and also check load/entry address if 2nd
# param was present
# input param:
# $1: fit image
# $2: if present, will also check load and entry validity
check_fit_image() {
FIT_IMAGE=$1
CHECK_OPT=$2
# check default cfg
CFG=$(fdtget ${FIT_IMAGE} /configurations default)
if [ "${CFG}" = "" ]; then
echo "ERROR: no default in /configurations"
exit 1
fi
# check image name
IMG_NAME=$(fdtget ${FIT_IMAGE} /configurations/${CFG} kernel)
if [ "${IMG_NAME}" = "" ]; then
echo "ERROR: no image name (kernel prop) in /configurations/${CFG}"
exit 1
fi
# check data
DATA=$(fdtget ${FIT_IMAGE} /images/${IMG_NAME} data)
if [ "${DATA}" = "" ]; then
echo "ERROR: no data in /images/${IMG_NAME}"
exit 1
fi
# check load
LOAD_D=$(fdtget ${FIT_IMAGE} /images/${IMG_NAME} load)
if [ "$LOAD_D" = "" ]; then
echo "ERROR: no load in /images/${IMG_NAME}"
exit 1
fi
# check entry
ENTRY_D=$(fdtget ${FIT_IMAGE} /images/${IMG_NAME} entry)
if [ "$ENTRY_D" = "" ]; then
echo "ERROR: no entry in /images/${IMG_NAME}"
exit 1
fi
if [ "${CHECK_OPT}" != "" ]; then
OFFSET=$(get_fit_data_offset ${FIT_IMAGE})
LOAD=$(printf "%x" ${LOAD_D})
if [ "`expr ${LOAD} : '.*\(....\)'`" != "${OFFSET}" ]; then
echo ERROR: load ${LOAD} is not align with data offset ${OFFSET}
exit 1
fi
LEN=$(echo ${DATA} | wc -w)
ENTRY=$(printf "%x" ${ENTRY_D})
END_D=`echo "${LOAD_D} + ${LEN} * 4" | bc`
END=$(printf "%x" ${END_D})
if [ ${ENTRY_D} -lt ${LOAD_D} -o ${END_D} -le ${ENTRY_D} ]; then
echo ERROR: entry ${ENTRY} is not in data ${LOAD} - ${END}
exit 1
fi
fi
}
# generate fit image: generate lk image in fit format
# input param:
# $1: fit image its file
# $2: key dir
# $3: output file
gen_fit_image() {
FIT_ITS=$1
KEYDIR=$2
OUT=$3
DTB=$(mktemp ${WORKDIR}/dtb.XXXXXX)
KEYDTSI=$(mktemp ${WORKDIR}/key.XXXXXX.dtsi)
KEYITS=$(mktemp ${WORKDIR}/key-fit-image.XXXXXX.its)
echo "/dts-v1/; / {};" | dtc -O dtb > ${DTB}
uboot-mkimage -f ${FIT_ITS} -k ${KEYDIR} -K ${DTB} ${OUT}
dtc -I dtb ${DTB} | tail -n+2 > ${KEYDTSI}
sed "s,\/dts-v1\/;,\0\n\/include\/ \"${KEYDTSI}\"," < ${FIT_ITS} > ${KEYITS}
uboot-mkimage -f ${KEYITS} -k ${KEYDIR} ${OUT}
# remove temporary files
rm -f ${DTB} ${KEYDTSI} ${KEYITS}
}
# gen_sbc_key_hash
# input param:
# $1: fit image
gen_sbc_key_hash() {
FDT_IMG=$1
TMP_FILE=$(mktemp ${WORKDIR}/col_rgn.XXXXXX.bin)
DEF_CONF=`fdtget -t s ${FDT_IMG} /configurations default`
SIG_NODE=`fdtget -l ${FDT_IMG} /configurations/${DEF_CONF}`
KEY_HINT=`fdtget -t s ${FDT_IMG} /configurations/${DEF_CONF}/${SIG_NODE} key-name-hint`
SHAX=`fdtget -t s ${FDT_IMG} /configurations/${DEF_CONF}/${SIG_NODE} algo | cut -d, -f1`
${WORKDIR}/fit-lk/extract_region ${FDT_IMG} ${TMP_FILE} /signature/key-${KEY_HINT}
KEY_HASH=`${SHAX}sum ${TMP_FILE} | cut -d " " -f 1`
echo "Hash algo: ${SHAX}"
echo "key_hash: ${KEY_HASH}"
for i in $(seq 1 8 ${#KEY_HASH}); do
end_i=`echo "$i+7" | bc`
qb=`echo ${KEY_HASH} | cut -c${i}-${end_i} | \
sed 's,\(..\)\(..\)\(..\)\(..\),\4\3\2\1,g'`
idx=`echo "${i} / 8" | bc`
echo "keyhash_${idx}: 0x"$qb
done
rm -f ${TMP_FILE}
}
gen_lk_fit_header() {
# generate temp files
BL_BIN=$(mktemp ${WORKDIR}/bl.XXXXXX.bin)
FIT_LK_IMG=${WORKDIR}/fit-lk.img
FIT_ITS=$(mktemp ${WORKDIR}/fit-bl-image.XXXXXX.its)
KEYDIR=${WORKDIR}/lk-key
PADDING=$(mktemp ${WORKDIR}/padding.XXXXXX.bin)
# copy raw lk binary to working directory
cp ${LK_OUT}/build-${LK_PROJECT}/${LK_BINARY} ${BL_BIN}
# generate a zero-size padding binary
touch ${PADDING}
# prepare rsa key
mkdir -p ${KEYDIR}
case "${SBC_RSA_ALGO}" in
rsa2048 | rsassa-pss2048)
cp -f ${MTK_KEY_DIR}/${SBC_KEY}.crt ${KEYDIR}/dev.crt
cp -f ${MTK_KEY_DIR}/${SBC_KEY}.pem ${KEYDIR}/dev.key
;;
rsa3072 | rsassa-pss3072)
cp -f ${MTK_KEY_DIR}/${SBC_KEY_RSA3072}.crt ${KEYDIR}/dev.crt
cp -f ${MTK_KEY_DIR}/${SBC_KEY_RSA3072}.pem ${KEYDIR}/dev.key
;;
rsa4096 | rsassa-pss4096)
cp -f ${MTK_KEY_DIR}/${SBC_KEY_RSA4096}.crt ${KEYDIR}/dev.crt
cp -f ${MTK_KEY_DIR}/${SBC_KEY_RSA4096}.pem ${KEYDIR}/dev.key
;;
*)
echo ${SBC_RSA_ALGO} ": not supported."
exit 1
;;
esac
# generate base its file
fitimage_emit_fit_header ${FIT_ITS}
fitimage_emit_fit_image_section ${FIT_ITS} ${PADDING} ${BL_BIN} \
${LK_LOADADDRESS} ${LK_ENTRYPOINT} ${IMAGE_HASH_ALGO}
fitimage_emit_fit_conf_section ${FIT_ITS} ${SBC_HASH_ALGO} ${SBC_RSA_ALGO} dev
fitimage_emit_fit_end ${FIT_ITS}
# 1st pass: generate fit-lk image to get padding size
gen_fit_image ${FIT_ITS} ${KEYDIR} ${FIT_LK_IMG}
check_fit_image ${FIT_LK_IMG}
# get data offset and calculate padding size
# padding size = lk load offset - data offset
DATA_OFFSET=$(get_fit_data_offset ${FIT_LK_IMG})
DATA_OFFSET_D=`echo "ibase=16;obase=A;${DATA_OFFSET}" | bc`
LK_LOAD_OFFSET_D=$(printf "%d" ${LK_LOAD_OFFSET})
PADDING_SIZE=`echo "${LK_LOAD_OFFSET_D} - ${DATA_OFFSET_D}" | bc`
rm -f ${PADDING}
dd if=/dev/zero of=${PADDING} bs=1 count=${PADDING_SIZE}
# 2nd pass: generate final fit-lk image
gen_fit_image ${FIT_ITS} ${KEYDIR} ${FIT_LK_IMG}
check_fit_image ${FIT_LK_IMG} all
cp ${FIT_LK_IMG} ${WORKDIR}/${LK_IMAGE}
# gen key hash for convenience
gen_sbc_key_hash ${FIT_LK_IMG}
# remove temp files
rm -f ${BL_BIN} ${FIT_ITS} ${PADDING}
rm -rf ${KEYDIR}
}
gen_lk_gfh_header() {
cp ${LK_OUT}/build-${LK_PROJECT}/${LK_BINARY} ${WORKDIR}/temp_gfh
if [ "${SECURE_BOOT_ENABLE}" = "yes" ]; then
cp ${MTK_KEY_DIR}/${SBC_KEY}.pem ${KEY_DIR}/root_prvk.pem
fi
python ${PBP_DIR}/pbp.py -g ${GFH_DIR}/${TARGET_PLATFORM}/gfh_conf.ini \
-i ${KEY_DIR}/lk_key.ini -func sign \
-o ${WORKDIR}/temp_gfh ${WORKDIR}/temp_gfh
if [ "${BOOTDEV_TYPE}" != "nand" ]; then
python ${DEV_INFO_HDR_TOOL} \
${BOOTDEV_TYPE} ${WORKDIR}/temp_gfh ${WORKDIR}/${LK_IMAGE}
else
cp ${WORKDIR}/temp_gfh ${WORKDIR}/${LK_IMAGE}
fi
}