#!/bin/sh
#
# install-kernel.sh
# Adapted from linux/scripts/package/builddeb (2003 Wichert Akkerman)
# Copyright 2024 - abc-nix (antiX Linux)
#
# Simplified script to install kernel components into debian/tmp for packaging.

set -e

is_enabled() {
	grep -q "^$1=y" include/config/auto.conf
}

if_enabled_echo() {
	if is_enabled "$1"; then
		echo -n "$2"
	elif [ $# -ge 3 ]; then
		echo -n "$3"
	fi
}

# Define the staging directory
STAGING_DIR=debian/tmp

# Create the staging directory
mkdir -p ${STAGING_DIR}/linux-image
mkdir -p ${STAGING_DIR}/linux-image-dbg
mkdir -p ${STAGING_DIR}/linux-headers
mkdir -p ${STAGING_DIR}/linux-libc-dev

install_linux_image() {
	local pdir=${STAGING_DIR}/linux-image

	# Install the kernel modules
	${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${pdir}" modules_install
	rm -f "${pdir}/lib/modules/${KERNELRELEASE}/build"

	# Install the System.map and config files
	mkdir -p "${pdir}/boot"
	cp System.map "${pdir}/boot/System.map-${KERNELRELEASE}"
	cp ${KCONFIG_CONFIG} "${pdir}/boot/config-${KERNELRELEASE}"

	# Install the kernel image
	installed_image_path="boot/vmlinuz-${KERNELRELEASE}"
	cp "$(${MAKE} -s -f ${srctree}/Makefile image_name)" "${pdir}/${installed_image_path}"

	install_maintainer_scripts "${pdir}"
}

install_linux_image_dbg() {
	local pdir=${STAGING_DIR}/linux-image-dbg
	local image_pdir=${STAGING_DIR}/linux-image

	# Extract debug symbols from kernel modules
	for module in $(find ${image_pdir}/lib/modules/ -name *.ko -printf '%P\n'); do
		module=lib/modules/${module}
		mkdir -p $(dirname ${pdir}/usr/lib/debug/${module})
		# only keep debug symbols in the debug file
		${OBJCOPY} --only-keep-debug ${image_pdir}/${module} ${pdir}/usr/lib/debug/${module}
		# strip original module from debug symbols
		${OBJCOPY} --strip-debug ${image_pdir}/${module}
		# then add a link to those
		${OBJCOPY} --add-gnu-debuglink=${pdir}/usr/lib/debug/${module} ${image_pdir}/${module}
	done

	# Re-sign stripped modules
	if is_enabled CONFIG_MODULE_SIG_ALL; then
		${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${image_pdir}" modules_sign
	fi

	# Build debug package
	# Different tools want the image in different locations
	# perf
	mkdir -p ${pdir}/usr/lib/debug/lib/modules/${KERNELRELEASE}/
	cp vmlinux ${pdir}/usr/lib/debug/lib/modules/${KERNELRELEASE}/
	# systemtap
	mkdir -p ${pdir}/usr/lib/debug/boot/
	ln -s ../lib/modules/${KERNELRELEASE}/vmlinux ${pdir}/usr/lib/debug/boot/vmlinux-${KERNELRELEASE}
	# kdump-tools
	ln -s lib/modules/${KERNELRELEASE}/vmlinux ${pdir}/usr/lib/debug/vmlinux-${KERNELRELEASE}
}

install_kernel_headers() {
	local pdir=${STAGING_DIR}/linux-headers
	local version=${KERNELRELEASE}

	"${srctree}/scripts/package/install-extmod-build" "${pdir}/usr/src/linux-headers-${version}"

	mkdir -p ${pdir}/lib/modules/${version}/
	ln -s /usr/src/linux-headers-${version} ${pdir}/lib/modules/${version}/build
}

install_libc_headers() {
	local pdir=${STAGING_DIR}/linux-libc-dev

	${MAKE} -f ${srctree}/Makefile headers
	${MAKE} -f ${srctree}/Makefile headers_install INSTALL_HDR_PATH=${pdir}/usr

	# Move asm headers to /usr/include/<libc-machine>/asm to match the structure
	# used by Debian-based distros (to support multi-arch)
	host_arch=$(dpkg-architecture -a${DEB_HOST_ARCH} -qDEB_HOST_MULTIARCH)
	mkdir -p ${pdir}/usr/include/${host_arch}
	mv ${pdir}/usr/include/asm ${pdir}/usr/include/${host_arch}/
}

install_maintainer_scripts() {
	local pdir=$1
	installed_image_path="boot/vmlinuz-${KERNELRELEASE}"
	debhookdir=${KDEB_HOOKDIR:-/etc/kernel}
	for script in postinst postrm preinst prerm; do
		mkdir -p "${pdir}${debhookdir}/${script}.d"

		cat <<-EOF > "debian/${script}"
		#!/bin/sh

		set -e

		# Pass maintainer script parameters to hook scripts
		export DEB_MAINT_PARAMS="\$*"

		# Tell initramfs builder whether it's wanted
		export INITRD=$(if_enabled_echo CONFIG_BLK_DEV_INITRD Yes No)

		test -d ${debhookdir}/${script}.d && run-parts --arg="${KERNELRELEASE}" --arg="/${installed_image_path}" ${debhookdir}/${script}.d
		exit 0
		EOF
		chmod 755 "debian/${script}"
	done
}


# Install each package component to the staging directory
install_linux_image
install_libc_headers
install_kernel_headers

# Check if the debug package entry exists to build this package
DEBUG_PACKAGE="Package: linux-image-${KERNELRELEASE}-dbg"
if grep -q -x "$DEBUG_PACKAGE" "debian/control"; then
	install_linux_image_dbg
fi


# Fix ownership and permissions
#~ chown -R root:root ${STAGING_DIR}
#~ chmod -R go-w,a+rX,ug-s ${STAGING_DIR}
