#!/usr/bin/env bash
function prepare_kernel_config_core_or_userpatches() {
[[ -z "${LINUXCONFIG}" ]] && exit_with_error "LINUXCONFIG not set: '${LINUXCONFIG}'"
if [[ -f $USERPATCHES_PATH/$LINUXCONFIG.config ]]; then
display_alert "Using kernel config provided by user" "userpatches/$LINUXCONFIG.config" "info"
kernel_config_source_filename="${USERPATCHES_PATH}/${LINUXCONFIG}.config"
elif [[ -f "${USERPATCHES_PATH}/config/kernel/${LINUXCONFIG}.config" ]]; then
display_alert "Using kernel config provided by user in config/kernel folder" "config/kernel/${LINUXCONFIG}.config" "info"
kernel_config_source_filename="${USERPATCHES_PATH}/config/kernel/${LINUXCONFIG}.config"
else
display_alert "Using kernel config file" "config/kernel/$LINUXCONFIG.config" "info"
kernel_config_source_filename="${SRC}/config/kernel/${LINUXCONFIG}.config"
fi
}
function kernel_config() {
[[ -z "${kernel_work_dir}" ]] && exit_with_error "kernel_work_dir is not set"
[[ ! -d "${kernel_work_dir}" ]] && exit_with_error "kernel_work_dir does not exist: ${kernel_work_dir}"
declare previous_config_filename=".config.armbian.previous"
declare kernel_config_source_filename=""
LOG_SECTION="kernel_config_initialize" do_with_logging do_with_hooks kernel_config_initialize
if [[ "${KERNEL_CONFIGURE}" == "yes" ]]; then
if [[ "${ARMBIAN_COMMAND}" != "rewrite-kernel-config" ]]; then
display_alert "Starting (interactive) kernel ${KERNEL_MENUCONFIG:-menuconfig}" "${LINUXCONFIG}" "debug"
run_kernel_make_dialog "${KERNEL_MENUCONFIG:-menuconfig}"
fi
LOG_SECTION="kernel_config_export" do_with_logging do_with_hooks kernel_config_export
fi
LOG_SECTION="kernel_config_finalize" do_with_logging do_with_hooks kernel_config_finalize
}
function kernel_config_initialize() {
display_alert "Configuring kernel" "${LINUXCONFIG}" "info"
cd "${kernel_work_dir}" || exit_with_error "kernel_work_dir does not exist: ${kernel_work_dir}"
if [[ -f "${kernel_work_dir}/.config" ]]; then
display_alert "Preserving previous kernel configuration" "${previous_config_filename}" "debug"
run_host_command_logged cp -pv "${kernel_work_dir}/.config" "${kernel_work_dir}/${previous_config_filename}"
fi
if [[ "${KERNEL_KEEP_CONFIG}" == yes && -f "${DEST}"/config/$LINUXCONFIG.config ]]; then
display_alert "Using previously-exported kernel config" "${DEST}/config/$LINUXCONFIG.config" "info"
run_host_command_logged cp -pv "${DEST}/config/${LINUXCONFIG}.config" "${kernel_work_dir}/.config"
else
prepare_kernel_config_core_or_userpatches
run_host_command_logged cp -pv "${kernel_config_source_filename}" "${kernel_work_dir}/.config"
fi
sed -i -e '$a\' "${kernel_work_dir}/.config"
cd "${kernel_work_dir}" || exit_with_error "kernel_work_dir does not exist before call_extensions_kernel_config: ${kernel_work_dir}"
call_extensions_kernel_config
cd "${kernel_work_dir}" || exit_with_error "kernel_work_dir does not exist: ${kernel_work_dir}"
run_kernel_make olddefconfig
display_alert "Kernel configuration" "${LINUXCONFIG}" "info"
}
function call_extensions_kernel_config() {
declare -A opts_val=()
declare -a opts_y=() opts_n=() opts_m=()
if ! declare -p kernel_config_modifying_hashes > /dev/null 2>&1; then
declare -ga kernel_config_modifying_hashes=()
fi
call_extension_method "armbian_kernel_config" <<- 'ARMBIAN_KERNEL_CONFIG'
*Armbian-core default hook point for pre-olddefconfig Kernel config modifications*
NOT for user consumption. Do NOT use this hook, this is internal to Armbian.
Instead, use `custom_kernel_config` which runs later and can undo anything done by this step.
IMPORTANT: this hook might be run multiple times, and one of them might not have a .config in place!
Therefore, please check with "if [[ -f .config ]]; then" if you want to modify the kernel config.
Either way, the hook _must_ add representative changes to the `kernel_config_modifying_hashes` array, for kernel config hashing.
Please note: Manually changing options doesn't check the validity of the .config file. Check for warnings in your build log.
ARMBIAN_KERNEL_CONFIG
# Custom hooks receive a clean / updated config; depending on their modifications, they may need to run olddefconfig again.
call_extension_method "custom_kernel_config" <<- 'CUSTOM_KERNEL_CONFIG'
*Kernel .config is in place, still clean from git version*
Called after ${LINUXCONFIG}.config is put in place (.config).
A good place to customize the .config directly.
Armbian default Kconfig modifications have already been applied and can be overriden.
IMPORTANT: this hook might be run multiple times, and one of them might not have a .config in place!
Therefore, please check with "if [[ -f .config ]]; then" if you want to modify the kernel config.
Either way, the hook _must_ add representative changes to the `kernel_config_modifying_hashes` array, for kernel config hashing.
Please note: Manually changing options doesn't check the validity of the .config file. Check for warnings in your build log.
CUSTOM_KERNEL_CONFIG
armbian_kernel_config_apply_opts_from_arrays
}
function kernel_config_canonicalize_modifications() {
declare -n announcements="${1}"
declare -a canonical=()
declare entry
for entry in "${announcements[@]}"; do
if [[ "${entry}" == *"="* ]] && [[ "${entry}" != CONFIG_* ]]; then
entry="CONFIG_${entry}"
fi
canonical+=("${entry}")
done
announcements=("${canonical[@]}")
}
function kernel_config_drop_modifications_matching_file() {
declare -n modifications="${1}"
declare config_file="${2}"
[[ -f "${config_file}" ]] || return 0
declare -A config_file_values=()
declare line key value
while IFS="" read -r line || [[ -n "${line}" ]]; do
case "${line}" in
CONFIG_*=*)
key="${line%%=*}"
value="${line#*=}"
;;
"# CONFIG_"*" is not set")
key="${line#\# }"
key="${key%% is not set}"
value="n"
;;
*)
continue
;;
esac
config_file_values["${key}"]="${value}"
done < "${config_file}"
declare -a kept=()
declare -i dropped=0
declare entry
for entry in "${modifications[@]}"; do
if [[ "${entry}" != *"="* ]]; then
kept+=("${entry}")
continue
fi
key="${entry%%=*}"
value="${entry#*=}"
[[ "${key}" != CONFIG_* ]] && key="CONFIG_${key}"
if [[ -v "config_file_values[${key}]" ]] && [[ "${config_file_values[${key}]}" == "${value}" ]]; then
display_alert "Kernel config modification already in the source config" "${entry}" "debug"
dropped+=1
continue
fi
kept+=("${entry}")
done
if [[ ${dropped} -gt 0 ]]; then
display_alert "Kernel config modifications that change nothing" "${dropped} of ${#modifications[@]} ignored for versioning" "debug"
fi
modifications=("${kept[@]}")
}
function kernel_config_finalize() {
if [[ -f "${kernel_work_dir}/${previous_config_filename}" ]]; then
if cmp "${kernel_work_dir}/.config" "${kernel_work_dir}/${previous_config_filename}"; then
display_alert "Kernel configuration unchanged from previous run" "optimizing for fast rebuilds" "cachehit"
run_host_command_logged cp -pv "${kernel_work_dir}/${previous_config_filename}" "${kernel_work_dir}/.config"
else
display_alert "Kernel configuration changed from previous build" "optimizing for correctness" "info"
fi
run_host_command_logged rm -f "${kernel_work_dir}/${previous_config_filename}"
fi
}
function kernel_config_export() {
run_kernel_make savedefconfig
mkdir -p "${DEST}"/config
display_alert "Exporting new kernel defconfig" "$DEST/config/$LINUXCONFIG.config" "info"
echo "# Armbian defconfig generated with ${KERNEL_MAJOR_MINOR}" > "${DEST}/config/${LINUXCONFIG}.config"
run_host_command_logged cat defconfig >> "${DEST}/config/${LINUXCONFIG}.config"
if [[ "${kernel_config_source_filename}" != "" ]]; then
display_alert "Exporting new kernel config - git commit pending" "${kernel_config_source_filename}" "info"
run_host_command_logged cp -pv "${DEST}/config/${LINUXCONFIG}.config" "${kernel_config_source_filename}"
fi
}