To figure out the kernel version and build without booting it, e.g. to install matching device drivers during an automated image build in something like CustoPiZer, use something like this:
function version_and_build_for_kernelimg() {
kernelimg=$1
# uncompressed kernel?
output=$(strings $kernelimg | grep 'Linux version' || echo)
if [ -z "$output" ]; then
# compressed kernel, needs more work, see https://raspberrypi.stackexchange.com/a/108107
pos=$(LC_ALL=C grep -P -a -b -m 1 --only-matching '\x1f\x8b\x08' $kernelimg | cut -f 1 -d :)
dd if=$kernelimg of=kernel.gz skip=$pos iflag=skip_bytes
output=$(gzip --decompress --stdout kernel.gz | strings | grep 'Linux version' || echo)
fi
version=$(echo $output | awk '{print $3}' | tr -d '+')
build=$(echo $output | awk -F"#" '{print $NF}' | awk '{print $1}')
if [[ -n "$version" && -n "$build" ]]; then
echo "Version: $kernel"
echo "Build: $build"
else
echo
echo "Cannot determine kernel version and build number for $kernelimg"
fi
}
Note that this has only been tested with kernels on RaspberryPi OS images, YMMV.