2023-03-15 22:22:25 +01:00
|
|
|
#!/usr/bin/env bash
|
2023-08-11 17:19:18 +02:00
|
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
2023-03-15 22:22:25 +01:00
|
|
|
#
|
2023-10-11 19:28:56 +02:00
|
|
|
# archboot-cpio.sh - modular tool for building initramfs images
|
2023-04-26 20:20:21 +02:00
|
|
|
# simplified, stripped down, optimized for size and speed
|
2023-03-16 07:36:15 +01:00
|
|
|
# by Tobias Powalowski <tpowa@archlinux.org>
|
2023-03-15 22:22:25 +01:00
|
|
|
|
|
|
|
shopt -s extglob
|
|
|
|
|
2023-07-24 20:28:58 +02:00
|
|
|
. /usr/lib/archboot/common.sh
|
2023-10-12 09:38:24 +02:00
|
|
|
. /usr/lib/archboot/cpio/cpio.sh
|
2023-03-15 22:22:25 +01:00
|
|
|
# needed files/directories
|
2023-10-12 08:46:11 +02:00
|
|
|
_CONFIG=""
|
2023-10-12 09:50:04 +02:00
|
|
|
_CPIO=/usr/lib/archboot/cpio/
|
2023-03-15 22:22:25 +01:00
|
|
|
# options and runtime data
|
2023-10-12 09:06:10 +02:00
|
|
|
_GENERATE_IMAGE=""
|
2023-10-12 09:10:33 +02:00
|
|
|
_TARGET_DIR=""
|
2023-10-12 10:51:43 +02:00
|
|
|
declare -A _addedmodules _modpaths
|
2023-03-15 22:22:25 +01:00
|
|
|
# Sanitize environment further
|
|
|
|
# GREP_OPTIONS="--color=always" will break everything
|
|
|
|
# CDPATH can affect cd and pushd
|
|
|
|
# LIBMOUNT_* options can affect findmnt and other tools
|
|
|
|
unset GREP_OPTIONS CDPATH "${!LIBMOUNT_@}"
|
|
|
|
|
2023-10-12 09:11:53 +02:00
|
|
|
_usage() {
|
2023-03-15 22:22:25 +01:00
|
|
|
cat <<EOF
|
2023-04-23 22:29:20 +02:00
|
|
|
ARCHBOOT CPIO
|
|
|
|
-------------
|
2023-04-26 20:20:21 +02:00
|
|
|
Tool for creating an archboot initramfs image.
|
2023-03-15 22:22:25 +01:00
|
|
|
|
2023-04-24 07:02:39 +02:00
|
|
|
-h Display this message and exit
|
2023-04-30 11:00:53 +02:00
|
|
|
|
|
|
|
-c <config> Use <config> file
|
|
|
|
-k <kernel> Use specified <kernel>
|
|
|
|
|
|
|
|
-g <path> Generate cpio image and write to specified <path>
|
|
|
|
-d <dir> Generate image into <dir>
|
2023-04-23 22:22:15 +02:00
|
|
|
|
|
|
|
usage: ${0##*/} <options>
|
2023-03-15 22:22:25 +01:00
|
|
|
EOF
|
|
|
|
}
|
|
|
|
|
2023-10-12 10:51:43 +02:00
|
|
|
_build_cpio() {
|
|
|
|
case "${_COMP}" in
|
|
|
|
cat) echo "Creating uncompressed initcpio image: ${_OUT}"
|
|
|
|
unset _COMP_OPTS
|
|
|
|
;;
|
|
|
|
*) echo "Creating ${_COMP} compressed initcpio image: ${_OUT}"
|
|
|
|
;;
|
|
|
|
xz) _COMP_OPTS=('-T0' '--check=crc32' "${_COMP_OPTS[@]}")
|
|
|
|
;;
|
|
|
|
lz4) _COMP_OPTS=('-l' "${_COMP_OPTS[@]}")
|
|
|
|
;;
|
|
|
|
zstd) _COMP_OPTS=('-T0' "${_COMP_OPTS[@]}")
|
|
|
|
;;
|
2023-03-15 22:22:25 +01:00
|
|
|
esac
|
|
|
|
# Reproducibility: set all timestamps to 0
|
|
|
|
find . -mindepth 1 -execdir touch -hcd "@0" "{}" +
|
|
|
|
# If this pipeline changes, |pipeprogs| below needs to be updated as well.
|
2023-03-17 08:50:04 +01:00
|
|
|
find . -mindepth 1 -printf '%P\0' |
|
|
|
|
sort -z |
|
2023-08-28 20:09:31 +02:00
|
|
|
LANG=C bsdtar --null -cnf - -T - |
|
|
|
|
LANG=C bsdtar --null -cf - --format=newc @- |
|
2023-10-12 10:51:43 +02:00
|
|
|
${_COMP} "${_COMP_OPTS[@]}" > "${_OUT}" || _abort "initcpio image creation failed!"
|
2023-03-15 22:22:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
preload_builtin_modules() {
|
|
|
|
local modname field value
|
2023-08-26 19:22:49 +02:00
|
|
|
# Prime the _addedmodules list with the builtins for this kernel.
|
2023-08-26 20:11:16 +02:00
|
|
|
# kmod>=27 and kernel >=5.2 required!
|
|
|
|
while IFS=.= read -rd '' modname field value; do
|
|
|
|
_addedmodules[${modname//-/_}]=2
|
|
|
|
case "$field" in
|
|
|
|
alias)
|
|
|
|
_addedmodules["${value//-/_}"]=2
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done <"$_d_kmoduledir/modules.builtin.modinfo"
|
2023-03-15 22:22:25 +01:00
|
|
|
}
|
|
|
|
|
2023-04-23 21:31:41 +02:00
|
|
|
if [[ -z "$1" ]]; then
|
2023-10-12 09:11:53 +02:00
|
|
|
_usage
|
2023-10-12 08:44:48 +02:00
|
|
|
exit 0
|
2023-04-23 21:31:41 +02:00
|
|
|
fi
|
2023-10-12 08:44:48 +02:00
|
|
|
_root_check
|
2023-07-24 20:28:58 +02:00
|
|
|
|
2023-03-15 22:22:25 +01:00
|
|
|
while :; do
|
2023-10-12 09:38:24 +02:00
|
|
|
case "${1}" in
|
|
|
|
-c) shift
|
|
|
|
${_CONFIG}="${1}"
|
2023-03-15 22:22:25 +01:00
|
|
|
;;
|
2023-10-12 09:38:24 +02:00
|
|
|
-k) shift
|
|
|
|
KERNEL="${1}"
|
2023-03-15 22:22:25 +01:00
|
|
|
;;
|
2023-10-12 09:38:24 +02:00
|
|
|
-d) shift
|
|
|
|
${_TARGET_DIR}="${1}"
|
2023-03-15 22:22:25 +01:00
|
|
|
;;
|
2023-10-12 09:38:24 +02:00
|
|
|
-g) shift
|
2023-10-12 10:51:43 +02:00
|
|
|
[[ -d "${1}" ]] && _abort "Invalid image path -- ${1} is a directory!"
|
2023-10-12 09:06:10 +02:00
|
|
|
if ! ${_GENERATE_IMAGE}="$(readlink -f "$1")" || [[ ! -e "${_GENERATE_IMAGE%/*}" ]]; then
|
2023-10-12 10:51:43 +02:00
|
|
|
_abort "Unable to write to path!" "${1}"
|
2023-03-15 22:22:25 +01:00
|
|
|
fi
|
|
|
|
;;
|
2023-10-12 09:38:24 +02:00
|
|
|
-h) _usage
|
2023-10-12 09:11:53 +02:00
|
|
|
exit 0
|
2023-03-15 22:22:25 +01:00
|
|
|
;;
|
2023-10-12 09:38:24 +02:00
|
|
|
*) _usage ;;
|
2023-03-15 22:22:25 +01:00
|
|
|
esac
|
|
|
|
shift
|
|
|
|
done
|
2023-10-12 08:49:48 +02:00
|
|
|
|
2023-09-04 09:33:55 +02:00
|
|
|
#shellcheck disable="SC1090"
|
2023-10-12 10:51:43 +02:00
|
|
|
! . "${_CONFIG}" 2>"${_NO_LOG}" && _abort "Failed to read configuration '%s'" "${_CONFIG}"
|
2023-09-03 14:22:59 +02:00
|
|
|
if [[ -z "${KERNEL}" ]]; then
|
2023-09-03 16:08:47 +02:00
|
|
|
msg "Trying to autodetect ${_RUNNING_ARCH} kernel..."
|
2023-09-03 14:22:59 +02:00
|
|
|
[[ "${_RUNNING_ARCH}" == "x86_64" || "${_RUNNING_ARCH}" == "riscv64" ]] && KERNEL="/usr/lib/modules/*/vmlinuz"
|
|
|
|
[[ "${_RUNNING_ARCH}" == "aarch64" ]] && KERNEL="/boot/Image.gz"
|
2023-03-15 22:22:25 +01:00
|
|
|
fi
|
2023-09-03 16:05:46 +02:00
|
|
|
# allow * in config
|
2023-09-04 11:48:33 +02:00
|
|
|
#shellcheck disable=SC2116,2086
|
2023-09-04 11:45:59 +02:00
|
|
|
KERNEL="$(echo ${KERNEL})"
|
2023-09-03 16:08:47 +02:00
|
|
|
msg "Using kernel: ${KERNEL}"
|
2023-09-03 14:22:59 +02:00
|
|
|
if [[ ! -f "${KERNEL}" ]]; then
|
2023-10-12 10:51:43 +02:00
|
|
|
_abort "kernel image does not exist!"
|
2023-09-03 14:22:59 +02:00
|
|
|
fi
|
2023-09-04 09:25:46 +02:00
|
|
|
_KERNELVERSION="$(_kver "${KERNEL}")"
|
2023-08-26 12:29:19 +02:00
|
|
|
_d_kmoduledir="/lib/modules/${_KERNELVERSION}"
|
2023-10-12 10:51:43 +02:00
|
|
|
[[ -d "$_d_kmoduledir" ]] || _abort "'$_d_kmoduledir' is not a valid kernel module directory"
|
2023-10-12 09:10:33 +02:00
|
|
|
_d_workdir="$(initialize_buildroot "${_KERNELVERSION}" "${_TARGET_DIR}")" || exit 1
|
2023-10-12 10:51:43 +02:00
|
|
|
_ROOTFS="${_TARGET_DIR}:-$_d_workdir/root}"
|
2023-04-16 16:56:02 +02:00
|
|
|
_hooks=("${HOOKS[@]}")
|
2023-03-15 22:22:25 +01:00
|
|
|
if (( ${#_hooks[*]} == 0 )); then
|
2023-10-12 10:51:43 +02:00
|
|
|
_abort "Invalid config: No hooks found"
|
2023-03-15 22:22:25 +01:00
|
|
|
fi
|
2023-10-12 09:06:10 +02:00
|
|
|
if [[ -n "${_GENERATE_IMAGE}" ]]; then
|
2023-03-15 22:22:25 +01:00
|
|
|
# check for permissions. if the image doesn't already exist,
|
|
|
|
# then check the directory
|
2023-10-12 09:06:10 +02:00
|
|
|
if [[ ( -e ${_GENERATE_IMAGE} && ! -w ${_GENERATE_IMAGE} ) ||
|
2023-10-12 09:08:23 +02:00
|
|
|
( ! -d ${_GENERATE_IMAGE%/*} || ! -w ${_GENERATE_IMAGE%/*} ) ]]; then
|
2023-10-12 10:51:43 +02:00
|
|
|
_abort "Unable to write to '%s'" "${_GENERATE_IMAGE}"
|
2023-03-15 22:22:25 +01:00
|
|
|
fi
|
2023-08-26 12:29:19 +02:00
|
|
|
msg "Starting build: '%s'" "${_KERNELVERSION}"
|
2023-10-12 09:10:33 +02:00
|
|
|
elif [[ -n "${_TARGET_DIR}" ]]; then
|
2023-08-26 12:29:19 +02:00
|
|
|
msg "Starting build: '%s'" "${_KERNELVERSION}"
|
2023-03-15 22:22:25 +01:00
|
|
|
else
|
2023-08-26 12:29:19 +02:00
|
|
|
msg "Starting dry run: '%s'" "${_KERNELVERSION}"
|
2023-03-15 22:22:25 +01:00
|
|
|
fi
|
|
|
|
# set functrace and trap to catch errors in add_* functions
|
|
|
|
declare -i _builderrors=0
|
|
|
|
preload_builtin_modules
|
|
|
|
map run_build_hook "${_hooks[@]}" || (( ++_builderrors ))
|
|
|
|
install_modules "${!_modpaths[@]}"
|
|
|
|
# this is simply a nice-to-have -- it doesn't matter if it fails.
|
2023-10-12 10:51:43 +02:00
|
|
|
ldconfig -r "${_ROOTFS}" &>"${_NO_LOG}"
|
|
|
|
# remove /var/cache/ldconfig/aux-cache for reproducibility
|
|
|
|
rm -f -- "${_ROOTFS}/var/cache/ldconfig/aux-cache"
|
2023-04-15 21:18:18 +02:00
|
|
|
# Set umask to create initramfs images as 600
|
2023-03-15 22:22:25 +01:00
|
|
|
umask 077
|
2023-10-12 09:06:10 +02:00
|
|
|
if [[ -n "${_GENERATE_IMAGE}" ]]; then
|
2023-10-12 10:51:43 +02:00
|
|
|
_build_cpio "${_GENERATE_IMAGE}" "${COMPRESSION}" || exit 1
|
2023-10-12 09:10:33 +02:00
|
|
|
elif [[ -n "${_TARGET_DIR}" ]]; then
|
2023-03-15 22:22:25 +01:00
|
|
|
msg "Build complete."
|
|
|
|
else
|
|
|
|
msg "Dry run complete, use -g IMAGE to generate a real image"
|
|
|
|
fi
|
|
|
|
exit $(( !!_builderrors ))
|
|
|
|
|
|
|
|
# vim: set ft=sh ts=4 sw=4 et:
|