363 lines
10 KiB
Bash
Executable File
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 "$@"
|
|
|
|
|