#!/bin/bash # SPDX-License-Identifier: GPL-2.0+ set -e kbuild_root=$(dirname $(readlink -f "$0")) declare -A cross_compile declare -A extra_kcflags declare -A target_root if [[ -r $kbuild_root/config.sh ]] ; then source $kbuild_root/config.sh || exit 1 fi #kbuild_options='CONFIG_DEBUG_SECTION_MISMATCH=y' #kbuild_options='C=1' kbuild_options="KALLSYMS_EXTRA_PASS=0" get_kernel_version() { local version=$(cat Makefile | grep '^VERSION = ' | sed 's/.* = //') local patchlevel=$(cat Makefile | grep '^PATCHLEVEL = ' | sed 's/.* = //') local sublevel=$(cat Makefile | grep '^SUBLEVEL = ' | sed 's/.* = //') echo "$version.$patchlevel.$sublevel" } version=$(get_kernel_version) # # Options parsing # do_compile_doc=0 do_menu_config=0 do_package_deb=0 opt_bootloader= opt_cmdline_file= opt_defconfig= opt_make_opts= while [[ $# != 0 ]] ; do option=$1 shift case $option in --bootloader) opt_bootloader=$1 if [[ ! -r $opt_bootloader ]] ; then echo "Boot loader file $opt_bootloader is not readable" exit 1 fi shift ;; --cmdline) opt_cmdline_file=$1 if [[ ! -r $opt_cmdline_file ]] ; then echo "Command line file $opt_cmdline_file is not readable" exit 1 fi shift ;; --config) do_menu_config=1 ;; --deb) do_package_deb=1 ;; --defconfig) opt_defconfig=$1 if [[ ! -r $opt_defconfig ]] ; then echo "defconfig file $opt_defconfig is not readable" exit 1 fi shift ;; --doc) do_compile_doc=1 ;; --) platform=auto ;; --*) echo "Unrecognized option $option" exit 1 ;; *) if [[ -z "$platform" ]] ; then platform=$option else opt_make_opts="$option $opt_make_opts" fi ;; esac done # # Platform # kcflags="-Werror -Wno-error=cpp" if [[ -z "$platform" || "$platform" == "auto" ]] ; then for f in $kbuild_root/platforms/*.sh ; do pattern=$(cat $f | grep "dir_pattern=" | head -1) pattern=${pattern/#dir_pattern=/} if [[ -n "$pattern" ]] ; then echo $PWD | grep -q "$pattern" || continue platform=$(basename -s .sh $f) break fi done fi if [[ ! -r "$kbuild_root/platforms/$platform.sh" ]] ; then echo "Unknown platform '$platform'. Supported platforms are" for f in $kbuild_root/platforms/*.sh ; do echo "- $(basename -s .sh $f)" done exit 1 fi source "${kbuild_root}/platforms/$platform.sh" || exit 1 # Apply version-specific kcflags, useful to suppress warnings based on the # kernel version. [[ -z "${extra_kcflags[$version]+_}" ]] || kcflags="$kcflags ${extra_kcflags[$version]}" # # Architecture # if [[ ! -r "$kbuild_root/arch/$arch.sh" ]] ; then echo "Unknown architecture '$arch'. Supported architectures are" for f in $kbuild_root/arch/*.sh ; do echo "- $(basename -s .sh $f)" done exit 1 fi source "${kbuild_root}/arch/$arch.sh" || exit 1 # Override the output directory for ARM for historical reasons case $arch in arm) output_dir=$PWD/output/arm32 ;; *) output_dir=$PWD/output/$arch ;; esac # # Build environment and tools # num_cpus=$(cat /proc/cpuinfo | grep '^processor\b' | wc -l) make="make ARCH=$arch O=$output_dir CROSS_COMPILE=${cross_compile[$arch]} ${extra_make_args}" pmake="$make -j$((num_cpus*2)) $opt_make_opts" echo "Compiling for platform $platform with $num_cpus CPUs" mkdir -p $output_dir/ if [[ -n "$opt_defconfig" ]] ; then mkdir -p $output_dir/arch/$arch/configs/ cp $opt_defconfig $output_dir/arch/$arch/configs/build_defconfig $make build_defconfig rm $output_dir/arch/$arch/configs/build_defconfig fi if [[ $do_menu_config == 1 ]] ; then $make menuconfig exit 0 fi # # Compile documentation if requested # if [[ $do_compile_doc == 1 ]] ; then $pmake DOCBOOKS='' htmldocs fi # # Compile the kernel, modules and DTBs # kernel_dtbs= for dtb in $dtbs ; do dtb=${dtb/:*/} kernel_dtbs="$kernel_dtbs $dtb" done $pmake $kbuild_options KCFLAGS="$kcflags" $image_kernel $kernel_dtbs grep 'CONFIG_MODULES=y' $output_dir/.config > /dev/null && modules=modules if [[ x$modules == xmodules ]] ; then $pmake $kbuild_options KCFLAGS="$kcflags" $modules fi version=$(cat $output_dir/include/generated/utsrelease.h | cut -d '"' -f 2) # # Create the image # if [[ -r "$kbuild_root/images/$image.sh" ]] ; then source "${kbuild_root}/images/$image.sh" || exit 1 eval make_${image}_image else image_file=$output_dir/arch/$arch/boot/$image fi # # Copy the files to their destination directories. # # The kernel image and DTBs are copied to both $target_dir/boot and $tftp_dir # (if available). When the image format is CrOS, installation to $tftp_dir is # skipped as Chrome OS devices can't boot from TFTP. # # The modules are installed to $target_dir if available, or to # $output_dir/modules otherwise. # target_dir=${target_dir:-${target_root[$arch]}} tftp_dir=${tftp_dir:-$tftp_root/$platform} copy_dtbs() { local dest_dir=$1 local dtb if [[ $image == FIT || $image == CrOS ]] ; then return fi for dtb in $dtbs ; do local src=${dtb/:*/} local dst=${dtb/*:/} dst=${dst/*\//} cp $output_dir/arch/${arch}/boot/dts/$src* $dest_dir/$dst done } if [[ -d "$target_dir" ]] ; then mkdir -p $target_dir/boot cp $image_file $target_dir/boot/ copy_dtbs $target_dir/boot/ fi if [[ $image != CrOS && -d "$tftp_dir" ]] ; then cp $image_file $tftp_dir/ copy_dtbs $tftp_dir/ fi if [[ x$modules == xmodules ]] ; then mod_path=${target_dir:-$output_dir/modules} mkdir -p $mod_path $pmake INSTALL_MOD_PATH=$mod_path modules_install fi # # Create the Debian package if requested # if [[ $do_package_deb == 1 ]] ; then $pmake bindeb-pkg fi # # Print status and terminate # echo "Kernel image available in $image_file" if [[ x$modules == xmodules ]] ; then echo "Kernel modules installed to $mod_path/lib/modules/$version" fi echo "Build $version completed at $(date)"