Add a useful script that can be used to convert a kernel module path to the relevant Kconfig symbol name. Examples showing how to use this is in the help at the top of the script. Signed-off-by: Brian Masney <bmasney@xxxxxxxxxx> --- scripts/kconfig/mod-to-kconfig.sh | 93 +++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100755 scripts/kconfig/mod-to-kconfig.sh diff --git a/scripts/kconfig/mod-to-kconfig.sh b/scripts/kconfig/mod-to-kconfig.sh new file mode 100755 index 000000000000..1b69b638ebf5 --- /dev/null +++ b/scripts/kconfig/mod-to-kconfig.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2023 Red Hat, Inc. All Rights Reserved. +# Written by Brian Masney <bmasney@xxxxxxxxxx> +# +# This script takes as input one or more kernel module names, and outputs +# the relevant Kconfig symbol name. This script was originally intended to help +# identify which Kconfig options are enabled inside an initramfs. +# +# x1:~/src/linux$ find /usr/lib/modules/`uname -r` -name *.ko.xz | \ +# ./scripts/kconfig/mod-to-kconfig.sh +# CONFIG_CRYPTO_USER +# CONFIG_CRYPTO_ESSIV +# CONFIG_CRYPTO_CHACHA20 +# CONFIG_CRYPTO_TWOFISH +# ... +# +# You can also use this to walk the modules.builtin file: +# +# x1:~/src/linux$ ./scripts/kconfig/mod-to-kconfig.sh < \ +# /usr/lib/modules/`uname -r`/modules.builtin +# +# Pipe the output of this script into scripts/kconfig/lookup.sh if you want to +# view the full Kconfig entries. +# +# Note that there is a fair bit of variability in the Makefiles across the +# kernel and this script won't match everything. It's only been written to +# cover the 95% use case. + +process_module() +{ + # We may have a full path, like /usr/lib/modules/`uname -r`/kernel/...`, + # or a relative path, like kernel/... that's found in modules.builtin. + local DIR + DIR=$(dirname "$1") + if [[ "${DIR}" =~ ^/ ]] ; then + DIR=${DIR##*/kernel/} + else + DIR=${DIR##kernel/} + fi + + # Handle compressed module names + local MOD_NAME + MOD_NAME=$(basename "$1") + MOD_NAME="${MOD_NAME/.xz/}" # CONFIG_FW_LOADER_COMPRESS_XZ + MOD_NAME="${MOD_NAME/.zst/}" # CONFIG_FW_LOADER_COMPRESS_ZSTD + MOD_NAME="${MOD_NAME/.ko/}" + MOD_NAME="${MOD_NAME/.c/}" + + local MAKEFILE + MAKEFILE="${DIR}/Makefile" + if [ ! -f "${MAKEFILE}" ] ; then + echo "Skipping $1 since ${MAKEFILE} is not found" >&2 + return 1 + fi + + # There's probably a more elegant way you could do this with sed or awk, + # however personally I find this approach more readable in this + # particular case. + local CONFIG + CONFIG=$(grep --before-context=200 -w -E "${MOD_NAME}(\.o|/)" \ + "${DIR}/Makefile" | grep CONFIG_ | tail -n 1 | \ + awk -F\( '{print $2}' | awk -F\) '{print $1}') + if [ "${CONFIG}" = "" ] ; then + echo "Skipping $1 since CONFIG cannot be determined" >&2 + return 1 + fi + echo "${CONFIG}" +} + +# Run this script from the toplevel kernel source directory. +SCRIPT_PATH=$(readlink -f "$0") +cd "$(dirname "${SCRIPT_PATH}")/../.." || exit 1 + +RET=0 +if [[ $# == 0 ]] ; then + # Read module paths from stdin + while read -r MODULE_PATH ; do + if ! process_module "${MODULE_PATH}" ; then + RET=1 + fi + done +else + # Read module paths from the command line arguments + for NUM in $(seq 1 "$#") ; do + if ! process_module "${!NUM}" ; then + RET=1 + fi + done +fi + +exit "${RET}" -- 2.41.0