在Debian上使用clang编译内核
有传言称,使用clang 12编译Linux内核可以启用LTO(链接时优化)和CFI功能。这里是在Debian上编译从www.kernel.org获取的内核的步骤。在以下步骤之前,请预先准备一个环境,例如使用apt-get build-dep linux/sid等命令,以便在不使用clang的情况下使用make bindeb-pkg进行编译。
安装CLang
从Debian的实验版/Sid/测试版安装clang、llvm和lld软件包。
安装Debian内核编译设置。
从Debian Experimental/Sid/Testing安装linux-config-5.15(或更高版本)。
编译工作
执行以下操作。然后会生成一个 *.deb 文件,使用 dpkg -i linux-image-某某.deb 命令来安装内核。如果不将XFS设为m以外的配置,将无法编译通过。执行ld.lld-12需要约7GB的内存和大约1小时的时间(适用于Raspberry Pi 4)。而在ld.lld-13中,内存占用减少到4GB。
cd /var/tmp
arch=`dpkg --print-architecture`
if [ $arch = amd64 ]; then
variant=amd64_none_amd64
march='-march=native'
elif [ $arch = arm64 ]; then
variant=arm64_none_arm64
march='-mcpu=native'
elif [ $arch = armhf ]; then
variant=armhf_none_armmp-lpae
march='-mcpu=native'
else
echo "Please find a suitable config of $arch."
exit 1
fi
KVER=5.15.1
exec </dev/null >build-log-${KVER}.txt 2>&1
set -xe
wget -T 10 -c https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-${KVER}.tar.xz
tar Jxf linux-${KVER}.tar.xz
cd linux-${KVER}
# 最適化レベルを強めるなら以下の2行を有効にする
#sed -i 's/-O2/-O3/g' Makefile
#sed -i 's/-Os/-Oz/g' Makefile
# install linux-config-5.15 from sid or experimental
xzcat /usr/src/linux-config-5.15/config.${variant}.xz >.config
cat >>.config <<EOF
CONFIG_MCORE2=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_INFO=n
CONFIG_LTO_CLANG_FULL=y
CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_CFI_CLANG=y
CONFIG_CFI_CLANG_SHADOW=y
#CONFIG_CFI_PERMISSIVE=y
CONFIG_SHADOW_CALL_STACK=y
CONFIG_INIT_STACK_ALL_ZERO=y
CONFIG_VGA_SWITCHEROO=n
CONFIG_VGA_ARB=n
CONFIG_DEVPORT=n
CONFIG_DEVMEM=n
CONFIG_DEVKMEM=n
CONFIG_SND_OSSEMUL=n
CONFIG_ZONE_DEVICE=y
CONFIG_DEVICE_PRIVATE=y
CONFIG_BPF_JIT_ALWAYS_ON=y
CONFIG_PREEMPT=y
CONFIG_DEBUG_PREEMPT=n
CONFIG_HZ_100=y
CONFIG_LATENCYTOP=y
CONFIG_HYPERVISOR_GUEST=n
CONFIG_KVM_GUEST=n
CONFIG_PARAVIRT=n
CONFIG_PARAVIRT_TIME_ACCOUNTING=y
CONFIG_XEN=n
CONFIG_IRQ_TIME_ACCOUNTING=y
CONFIG_CLEAN_CACHE=y
CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y
CONFIG_UBSAN=y
CONFIG_UBSAN_SANITIZE_ALL=y
CONFIG_UBSAN_BOUNDS=y
CONFIG_UBSAN_ARRAY_BOUNDS=y
CONFIG_UBSAN_UNREACHABLE=y
CONFIG_UBSAN_SHIFT=y
CONFIG_UBSAN_OBJECT_SIZE=n
CONFIG_STACK_VALIDATION=y
CONFIG_WQ_WATCHDOG=y
CONFIG_XFS_FS=n
EOF
if [ $arch = armhf ]; then
yes '' |
chrt --batch 0 nice -19 /usr/bin/time -v make -j `nproc` ARCH=arm V=1 LLVM=1 LLVM_IAS=1 \
KCFLAGS="-pipe ${march} -fintegrated-cc1 -mllvm -polly -mllvm -polly-ast-use-context -mllvm -polly-invariant-load-hoisting -mllvm -polly-opt-fusion=max -mllvm -polly-run-inliner -mllvm -polly-vectorizer=stripmine -mllvm -polly-run-dce" \
LOCALVERSION=-clang13ltopolly \
bindeb-pkg
else
yes '' |
chrt --batch 0 nice -19 /usr/bin/time -v make -j `nproc` V=1 LLVM=1 LLVM_IAS=1 \
KCFLAGS="-pipe ${march} -fintegrated-cc1 -mllvm -polly -mllvm -polly-ast-use-context -mllvm -polly-invariant-load-hoisting -mllvm -polly-opt-fusion=max -mllvm -polly-run-inliner -mllvm -polly-vectorizer=stripmine -mllvm -polly-run-dce" \
LOCALVERSION=-clang13ltopolly \
bindeb-pkg
fi