Files
los-kernel-dodge-sukisu-susfs/build.sh
2025-11-27 14:08:33 -05:00

363 lines
10 KiB
Bash
Executable File

#!/usr/bin/env bash
usage() {
cat << EOF
Usage: $(basename "$0") [COMMAND]
Commands:
build Build the kernel (default)
menuconfig Run menuconfig and save customizations
repack Repack stock boot image with custom kernel
download Download latest LineageOS boot image
help Show this help message
Examples:
$(basename "$0") # Build the kernel
$(basename "$0") build # Build the kernel
$(basename "$0") menuconfig # Configure kernel interactively
$(basename "$0") repack # Repack stock_boot.img with new kernel (auto-downloads if missing)
$(basename "$0") download # Download latest LineageOS boot.img for dodge
EOF
exit 0
}
set_basedir() {
BASEDIR=$(realpath "$(dirname -- "$(realpath -- "${BASH_SOURCE[0]}")")/..")
}
ensure_repo_initialized() {
if [ ! -d "$BASEDIR/.repo" ]; then
echo ".dir missing, initializing..."
pushd "$BASEDIR" > /dev/null
repo init -u "$BASEDIR/meta" --git-lfs
repo sync
popd > /dev/null
fi
}
download_magisk() {
if [ ! -d "$BASEDIR/prebuilts/magisk" ]; then
echo "Magisk binaries missing, downloading..."
mkdir -p "$BASEDIR/prebuilts/magisk"
pushd "$BASEDIR/prebuilts/magisk" > /dev/null
wget "https://github.com/topjohnwu/Magisk/releases/download/v29.0/Magisk-v29.0.apk" || curl -OL "https://github.com/topjohnwu/Magisk/releases/download/v29.0/Magisk-v29.0.apk"
unzip "Magisk-v29.0.apk"
popd > /dev/null
fi
}
setup_toolchain_vars() {
GCCDIR="$BASEDIR/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9"
GCCDIR32="$BASEDIR/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9"
CLANGDIR="$BASEDIR/prebuilts/clang/host/linux-x86/clang-r547379"
KERNELBUILDTOOLS="$BASEDIR/prebuilts/kernel-build-tools/linux-x86"
MAKEOPTS=(
O="$BASEDIR/work"
ARCH=arm64
PATH="$CLANGDIR/bin:$GCCDIR/bin:$KERNELBUILDTOOLS/bin:$PATH"
LD_LIBRARY_PATH="$CLANGDIR/lib"
LLVM=1
CROSS_COMPILE="$GCCDIR/bin/aarch64-linux-android-"
CROSS_COMPILE_ARM32="$GCCDIR32/bin/arm-linux-androideabi-"
CLANG_TRIPLE=aarch64-linux-gnu-
)
}
prepare_kernel_source() {
echo "Preparing source..."
pushd "$BASEDIR/kernel/oneplus/sm8750" > /dev/null
git reset --hard
git clean -fd
ln -s "${BASEDIR}/external/SukiSU-Ultra" "KernelSU"
ln -s "${BASEDIR}/external/SukiSU-Ultra/kernel" "drivers/kernelsu"
popd > /dev/null
}
add_sukisu() {
pushd "$BASEDIR/kernel/oneplus/sm8750" > /dev/null
MOD=false
grep -q "kernelsu" "drivers/Makefile" || printf "\nobj-\$(CONFIG_KSU) += kernelsu/\n" >> "drivers/Makefile" || echo "[+] Modified Makefile."
grep -q "source \"drivers/kernelsu/Kconfig\"" "drivers/Kconfig" || sed -i "/endmenu/i\source \"drivers/kernelsu/Kconfig\"" "drivers/Kconfig" && echo "[+] Modified Kconfig."
popd > /dev/null
}
add_susfs() {
pushd "$BASEDIR/kernel/oneplus/sm8750" > /dev/null
cp "${BASEDIR}/external/susfs4ksu/kernel_patches/fs/"* "fs/"
cp "${BASEDIR}/external/susfs4ksu/kernel_patches/include/linux/"* "include/linux/"
patch --fuzz=3 -p1 < "${BASEDIR}/external/susfs4ksu/kernel_patches/50_add_susfs_in_gki-android15-6.6.patch"
popd > /dev/null
}
configure_kernel() {
pushd "$BASEDIR/kernel/oneplus/sm8750" > /dev/null
mkdir -p "$BASEDIR/out"
mkdir -p "$BASEDIR/work"
make ${MAKEOPTS[@]} mrproper
make ${MAKEOPTS[@]} gki_defconfig
scripts/kconfig/merge_config.sh -m -O "$BASEDIR/work" \
"$BASEDIR/work/.config" \
arch/arm64/configs/vendor/sun_perf.config \
arch/arm64/configs/vendor/oplus/sun_perf.config
if [ -e "${BASEDIR}/.config" ]; then
echo "Adding custom configuration..."
scripts/kconfig/merge_config.sh -m -O "${BASEDIR}/work" \
"${BASEDIR}/work/.config" \
"${BASEDIR}/.config"
fi
echo "CONFIG_DODGE_DTB=y" >> "$BASEDIR/work/.config"
echo "CONFIG_OPLUS_DEVICE_DTBS=y" >> "$BASEDIR/work/.config"
echo "CONFIG_COMPAT=y" >> "$BASEDIR/work/.config"
echo "CONFIG_COMPAT_VDSO=y" >> "$BASEDIR/work/.config"
make ${MAKEOPTS[@]} olddefconfig
popd > /dev/null
}
build_kernel() {
pushd "$BASEDIR/kernel/oneplus/sm8750" > /dev/null
make ${MAKEOPTS[@]} \
KCFLAGS="-Wno-error=frame-larger-than=" \
-j$(nproc) 2>&1 | tee "$BASEDIR/work/build.log"
popd > /dev/null
}
prepare_anykernel() {
echo "Preparing AnyKernel3 package..."
rm -rf "${BASEDIR}/work/AnyKernel3"
mkdir -p "${BASEDIR}/work/AnyKernel3"
cp -ra "${BASEDIR}/external/AnyKernel3/"* "${BASEDIR}/work/AnyKernel3/"
cp "${BASEDIR}/meta/anykernel.sh" "${BASEDIR}/work/AnyKernel3/anykernel.sh"
cp "${BASEDIR}/prebuilts/magisk/lib/arm64-v8a/libbusybox.so" "${BASEDIR}/work/AnyKernel3/tools/busybox"
cp "${BASEDIR}/prebuilts/magisk/lib/arm64-v8a/libmagiskboot.so" "${BASEDIR}/work/AnyKernel3/tools/magiskboot"
chmod +x "${BASEDIR}/work/AnyKernel3/tools/"*
echo "Copying kernel Image..."
cp "${BASEDIR}/work/arch/arm64/boot/Image" "${BASEDIR}/work/AnyKernel3/"
}
create_flashable_zip() {
echo "Creating flashable zip..."
KERNEL_VERSION=$(cat "${BASEDIR}/kernel/oneplus/sm8750/include/config/kernel.release" 2>/dev/null || echo "unknown")
OUTPUT_ZIP="${BASEDIR}/out/LiteKernel-${KERNEL_VERSION}-$(date +%Y%m%d-%H%M%S).zip"
pushd "${BASEDIR}/work/AnyKernel3" > /dev/null
zip -r9 "${OUTPUT_ZIP}" * -x .git README.md .gitignore ./*.zip
popd > /dev/null
echo "Build complete!"
echo "Flashable zip: ${OUTPUT_ZIP}"
}
run_menuconfig() {
set_basedir
setup_toolchain_vars
mkdir -p "$BASEDIR/out"
mkdir -p "$BASEDIR/work"
pushd "$BASEDIR/kernel/oneplus/sm8750" > /dev/null
echo "Generating base configuration..."
make ${MAKEOPTS[@]} mrproper
make ${MAKEOPTS[@]} gki_defconfig
scripts/kconfig/merge_config.sh -m -O "$BASEDIR/work" \
"$BASEDIR/work/.config" \
arch/arm64/configs/vendor/sun_perf.config \
arch/arm64/configs/vendor/oplus/sun_perf.config
make ${MAKEOPTS[@]} olddefconfig
cp "$BASEDIR/work/.config" "$BASEDIR/work/.config.base"
if [ -e "${BASEDIR}/.config" ]; then
echo "Merging existing custom configuration..."
scripts/kconfig/merge_config.sh -m -O "${BASEDIR}/work" \
"${BASEDIR}/work/.config" \
"${BASEDIR}/.config"
make ${MAKEOPTS[@]} olddefconfig
fi
make ${MAKEOPTS[@]} menuconfig
extract_custom_config
popd > /dev/null
}
extract_custom_config() {
echo "Extracting custom configuration differences..."
if [ ! -f "$BASEDIR/work/.config.base" ]; then
echo "Warning: No base config found for comparison"
return
fi
> "$BASEDIR/.config"
declare -A base_configs
declare -A current_configs
while IFS= read -r line; do
if [[ "$line" =~ ^CONFIG_([^=]+)= ]]; then
config_name="${BASH_REMATCH[1]}"
base_configs["$config_name"]="$line"
elif [[ "$line" =~ ^#\ (CONFIG_[^\ ]+)\ is\ not\ set ]]; then
config_name="${BASH_REMATCH[1]#CONFIG_}"
base_configs["$config_name"]="$line"
fi
done < "$BASEDIR/work/.config.base"
while IFS= read -r line; do
if [[ "$line" =~ ^CONFIG_([^=]+)= ]]; then
config_name="${BASH_REMATCH[1]}"
current_configs["$config_name"]="$line"
elif [[ "$line" =~ ^#\ (CONFIG_[^\ ]+)\ is\ not\ set ]]; then
config_name="${BASH_REMATCH[1]#CONFIG_}"
current_configs["$config_name"]="$line"
fi
done < "$BASEDIR/work/.config"
for config_name in "${!current_configs[@]}"; do
if [[ "${base_configs[$config_name]}" != "${current_configs[$config_name]}" ]]; then
echo "${current_configs[$config_name]}" >> "$BASEDIR/.config"
fi
done
if [ -s "$BASEDIR/.config" ]; then
sort -o "$BASEDIR/.config" "$BASEDIR/.config"
echo ""
echo "Custom configuration saved to: $BASEDIR/.config"
echo "Changes from base configuration:"
cat "$BASEDIR/.config"
echo ""
else
echo "No configuration changes from base detected."
rm -f "$BASEDIR/.config"
fi
}
download_lineageos_boot() {
set_basedir
echo "Fetching latest LineageOS build information for dodge..."
if ! command -v python3 &> /dev/null; then
echo "Error: python3 is required but not found"
return 1
fi
BOOT_URL=$(curl -s "https://download.lineageos.org/api/v2/devices/dodge/builds" | python3 -c 'import sys,json;d=json.load(sys.stdin);boot=[f for f in d[0]["files"] if f["filename"]=="boot.img"][0];print(boot["url"])' 2>/dev/null)
if [ -z "$BOOT_URL" ]; then
echo "Error: Failed to fetch boot.img URL from LineageOS API"
return 1
fi
echo "Found boot.img URL: $BOOT_URL"
echo "Downloading boot.img..."
wget -O "${BASEDIR}/stock_boot.img" "$BOOT_URL" || curl -L -o "${BASEDIR}/stock_boot.img" "$BOOT_URL"
if [ ! -f "${BASEDIR}/stock_boot.img" ]; then
echo "Error: Failed to download boot.img"
return 1
fi
echo "Boot image saved to: ${BASEDIR}/stock_boot.img"
}
repack_boot_image() {
set_basedir
download_magisk
if [ ! -f "${BASEDIR}/stock_boot.img" ]; then
echo "stock_boot.img not found, attempting to download from LineageOS..."
download_lineageos_boot || return 1
fi
if [ ! -f "${BASEDIR}/work/arch/arm64/boot/Image" ]; then
echo "Error: Kernel Image not found at ${BASEDIR}/work/arch/arm64/boot/Image"
echo "Please build the kernel first using: $(basename "$0") build"
return 1
fi
MAGISKBOOT="${BASEDIR}/prebuilts/magisk/lib/x86_64/libmagiskboot.so"
chmod +x "${MAGISKBOOT}"
echo "Repacking boot image..."
rm -rf "${BASEDIR}/out/repack"
mkdir -p "${BASEDIR}/out/repack"
pushd "${BASEDIR}/out/repack" > /dev/null
${MAGISKBOOT} unpack "${BASEDIR}/stock_boot.img"
cp "${BASEDIR}/work/arch/arm64/boot/Image" kernel
${MAGISKBOOT} repack "${BASEDIR}/stock_boot.img" "${BASEDIR}/out/new_boot.img"
popd > /dev/null
echo ""
echo "Boot image repacked successfully!"
echo "Output: ${BASEDIR}/out/new_boot.img"
}
build() {
set_basedir
ensure_repo_initialized
download_magisk
setup_toolchain_vars
prepare_kernel_source
add_sukisu
add_susfs
configure_kernel
build_kernel
prepare_anykernel
create_flashable_zip
}
main() {
local command="${1:-build}"
case "$command" in
build)
build
;;
menuconfig)
run_menuconfig
;;
repack)
repack_boot_image
;;
download)
download_lineageos_boot
;;
help|--help|-h)
usage
;;
*)
echo "Error: Unknown command '$command'"
echo ""
usage
;;
esac
}
main "$@"