# SPDX-License-Identifier: GPL-2.0 # #!/bin/bash function usage () { echo $0 'Check for kernel defconfig mismacth' echo 'Usage:' echo ' '$0' [-c] [-u] [defconfig-files]' echo ' -c Check changed defconfigs from last git commit' echo ' -u Update defconfig if no mismatch is found' echo ' -h This help' exit 0 } function build_config_parse () { build_config=$1 CC="undef" LD="undef" NM="undef" OBJCOPY="undef" cc=`cat ${build_config} | grep ^CC= | cut -d'=' -f 2` ld=`cat ${build_config} | grep ^LD= | cut -d'=' -f 2` nm=`cat ${build_config} | grep ^NM= | cut -d'=' -f 2` objcopy=`cat ${build_config} | grep ^OBJCOPY= | cut -d'=' -f 2` if [ $cc == clang ]; then toolchain=`cat ${build_config} | grep CLANG_PREBUILT_BIN | cut -d'=' -f 2` CC="${PWD}/../${toolchain}/${cc}" LD="${PWD}/../${toolchain}/${ld}" NM="${PWD}/../${toolchain}/${nm}" OBJCOPY="${PWD}/../${toolchain}/${objcopy}" else toolchain=`cat ${build_config} | grep LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN | cut -d'=' -f 2` cross_compile=`cat ${build_config} | grep ^CROSS_COMPILE | cut -d'=' -f 2` CC="${PWD}/../${toolchain}/${cross_compile}${cc}" fi } function build_config_read () { build_config_parse ${ARM_CONFIG} CC_ARM="${CC}" LD_ARM="${LD}" build_config_parse ${ARM64_CONFIG} CC_ARM64="${CC}" LD_ARM64="${LD}" NM_ARM64="${NM}" OBJCOPY_ARM64="${OBJCOPY}" build_config_parse ${ARM64_GCC_CONFIG} CC_ARM64_GCC="${CC}" LD_ARM64_GCC="${LD}" build_config_parse ${KASAN_CONFIG} CC_KASAN="${CC}" LD_KASAN="${LD}" build_config_parse ${UBSAN_CONFIG} CC_UBSAN="${CC}" LD_UBSAN="${LD}" } function toolchain_check () { if [ ! -d "../${TOOLCHAIN_CLANG_PATH}/linux-x86" ]; then echo "CLANG does not exist, clone it" mkdir -p "../${TOOLCHAIN_CLANG_PATH}" cd "../${TOOLCHAIN_CLANG_PATH}" git clone "http://gerrit.mediatek.inc:8080/${TOOLCHAIN_CLANG_REPO}" cd linux-x86 git reset --hard ${TOOLCHAIN_CLANG_COMMIT} else echo "update CLANG to specific commit" cd "../${TOOLCHAIN_CLANG_PATH}/linux-x86" git reset --hard ${TOOLCHAIN_CLANG_COMMIT} fi cd ${KERNEL_PATH} if [ ! -d "../${TOOLCHAIN_GCC_PATH}/bin" ]; then echo "GCC does not exist, clone it" rm -rf "../${TOOLCHAIN_GCC_PATH}" mkdir -p "../prebuilts/gcc/linux-x86/aarch64" cd "../prebuilts/gcc/linux-x86/aarch64" git clone "http://gerrit.mediatek.inc:8080/${TOOLCHAIN_GCC_REPO}" -b alps-trunk-r0.basic else echo "update GCC to the latest codebase" cd "../${TOOLCHAIN_GCC_PATH}" git pull fi cd ${KERNEL_PATH} } CONFIGS= UPDATE=0 CHECK_COMMIT=0 CHECK_SERVICE=0 CC= LD= NM= OBJCOPY= CC_ARM= CC_ARM64= CC_ARM64_GCC= CC_KASAN= CC_UBSAN= LD_ARM= LD_ARM64= LD_ARM64_GCC= LD_KASAN= LD_UBSAN= NM_ARM64= OBJCOPY_ARM64= ARM_CONFIG='build.config.mtk.arm' ARM64_CONFIG='build.config.mtk.aarch64' ARM64_GCC_CONFIG='build.config.mtk.aarch64.gcc' KASAN_CONFIG='build.config.mtk.aarch64.kasan' UBSAN_CONFIG='build.config.mtk.aarch64.ubsan' TOOLCHAIN_CLANG_PATH='prebuilts/clang/host' TOOLCHAIN_GCC_PATH='prebuilts/gcc/linux-x86/aarch64/aarch64-linux-gnu-6.3.1' TOOLCHAIN_CLANG_REPO='platform/prebuilts/clang/host/linux-x86' TOOLCHAIN_GCC_REPO='alps/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-gnu-6.3.1' TOOLCHAIN_CLANG_COMMIT='252aba16f513a857bc923172f67b0e55e23de35f' KERNEL_PATH=${PWD} build_config_read echo "CC_ARM=${CC_ARM}" echo "CC_ARM64=${CC_ARM64}" echo "CC_ARM64_GCC=${CC_ARM64_GCC}" echo "CC_KASAN=${CC_KASAN}" echo "CC_UBSAN=${CC_UBSAN}" echo "LD_ARM=${LD_ARM}" echo "LD_ARM64=${LD_ARM64}" echo "LD_ARM64_GCC=${LD_ARM64_GCC}" echo "LD_KASAN=${LD_KASAN}" echo "LD_UBSAN=${LD_UBSAN}" echo "NM_ARM64=${NM_ARM64}" echo "OBJCOPY_ARM64=${OBJCOPY_ARM64}" while getopts "cuh" opt; do case $opt in c) if [ $# == 2 ]; then CHECK_COMMIT=$2 if [ ${CHECK_COMMIT} == FETCH_HEAD ]; then CHECK_SERVICE=1 echo Checking from check service fi else CHECK_COMMIT="HEAD" fi KCONFIG=`git show ${CHECK_COMMIT} --stat | gawk '/\/Kconfig.* +\| +[0-9]*/{print $1}'` if [ ".$KCONFIG" != "." ]; then echo From git commit: Checking all defconfig due to Kconfig is changed. CONFIGS=`grep -rl "CONFIG_MTK_PLATFORM" arch/arm/configs arch/arm64/configs` fi CONFIGS+=" `git show ${CHECK_COMMIT} --stat-width=500 | gawk '/arch\/(arm64|arm)\/configs\/.*_defconfig +\| +[0-9]*/{print $1}'`" CONFIGS=`echo $CONFIGS | xargs -n1 | sort -u | xargs` if [ ".$CONFIGS" != "." ]; then echo From git commit: Checking $CONFIGS else echo "Nothing to check" exit 0 fi ;; u) UPDATE=1 ;; h) usage ;; esac done if [ $# == 0 ]; then usage fi if [ $CHECK_COMMIT == 0 ]; then shift $((OPTIND-1)) CONFIGS="${CONFIGS} $*" fi check_defconfig() { CONFIG=${1} UPDATE=${2} CC_ARM=${3} CC_ARM64=${4} CC_ARM64_GCC=${5} CC_KASAN=${6} CC_UBSAN=${7} LD_ARM=${8} LD_ARM64=${9} LD_ARM64_GCC=${10} LD_KASAN=${11} LD_UBSAN=${12} NM_ARM64=${13} OBJCOPY_ARM64=${14} FAIL=0 echo "Checking ${CONFIG}" if [ ! -e ${CONFIG} ]; then echo warning: defconfig file $CONFIG not found return $FAIL fi echo $CONFIG | grep arch/arm64 > /dev/null RETVAL=$? if [ $RETVAL != 0 ]; then ARCH=arm CC=${CC_ARM} LD=${LD_ARM} else ARCH=arm64 CC=${CC_ARM64} LD=${LD_ARM64} NM=${NM_ARM64} OBJCOPY=${OBJCOPY_ARM64} fi echo $CONFIG | grep kasan > /dev/null RETVAL=$? if [ $RETVAL == 0 ]; then CC=${CC_KASAN} LD=${LD_KASAN} fi echo $CONFIG | grep ubsan > /dev/null RETVAL=$? if [ $RETVAL == 0 ]; then CC=${CC_UBSAN} LD=${LD_UBSAN} fi OUT=out-$$ mkdir ${OUT} ARGS=() if [ -n "${CC}" ]; then ARGS+=("CC=${CC}") fi if [ -n "${LD}" ]; then ARGS+=("LD=${LD}") fi if [ -n "${NM}" ]; then ARGS+=("NM=${NM}") fi if [ -n "${OBJCOPY}" ]; then ARGS+=("OBJCOPY=${OBJCOPY}") fi CMD="make ARCH=${ARCH} ${ARGS[@]} O=${OUT} `basename ${CONFIG}` savedefconfig 2>&1" echo $CMD OUTPUT="$(${CMD})" RETVAL=$? echo "$OUTPUT" if [ $RETVAL != 0 ]; then echo error: Make ${CONFIG} error rm -rf ${OUT} FAIL=1 return $FAIL fi # Check if there is a warning message if echo "$OUTPUT" | grep -q "^warning:"; then echo error: there is a warning message with Kconfig rm -rf ${OUT} FAIL=1 return $FAIL fi # Check option mismatch gawk 'BEGIN{lastf="";} { if (lastf != FILENAME) { if (lastf != "") CHECK=1; lastf=FILENAME; } } \ /CONFIG_/ { match($0, /CONFIG_[^ =]*/); option=substr($0, RSTART, RLENGTH); \ if (CHECK==1) { if (option in opts && opts[option]==$0) delete opts[option]; } \ else { if (option in opts && opts[option]!=$0) dups[option]=$0; opts[option]=$0; } } \ END { C=0; RET=0; for (i in dups) { RET=1; C++; printf("error: %s duplicate in defconfig\n", i); } \ for (i in opts) { RET=1; C++; printf("error: %s mismatch\n", i); } exit(RET);}' ${CONFIG} ${OUT}/.config RETVAL=$? if [ $RETVAL != 0 ]; then echo error: ${CONFIG}: defconfig mismatch. Please check Kconfig and follow SOP to update _defconfig. rm -rf ${OUT} FAIL=1 return $FAIL fi if [ $UPDATE == 0 ]; then # Compare output, make sure format is correct OUTPUT="$(diff -u ${OUT}/defconfig ${CONFIG} 2>&1)" RETVAL=$? if [ $RETVAL != 0 ]; then echo error: ${CONFIG} compare error. Please follow SOP to update _defconfig echo "$OUTPUT" rm -rf ${OUT} FAIL=1 return $FAIL fi else cp ${OUT}/defconfig ${CONFIG} fi rm -rf ${OUT} return $FAIL } export -f check_defconfig toolchain_check parallel check_defconfig ::: $CONFIGS ::: $UPDATE ::: $CC_ARM ::: $CC_ARM64 ::: $CC_ARM64_GCC ::: $CC_KASAN ::: $CC_UBSAN ::: $LD_ARM ::: $LD_ARM64 ::: $LD_ARM64_GCC ::: $LD_KASAN ::: $LD_UBSAN ::: $NM_ARM64 ::: $OBJCOPY_ARM64 RETVAL=$? if [ $RETVAL != 0 ]; then echo echo Please check the following wiki for detail, thanks! echo http://wiki.mediatek.inc/display/KernelStandardization/Check+defconfig+in+kernel+preflight echo http://wiki.mediatek.inc/display/KernelStandardization/SOP+to+update+kernel+config fi if [ ${CHECK_SERVICE} == 1 ]; then rm -rf /tmp/prebuilts echo Remove toolchain in check service fi exit $RETVAL