mirror of
https://salsa.debian.org/kernel-team/initramfs-tools.git
synced 2026-01-29 10:54:35 +00:00
This facilitates mkinitramfs building. It is intended as fix for the not possible ldconfig run inside the symlink tree. It should also allow to cleanup the copy_exec() mess. This also allows to no longer shipp duplicate busybox copies in initramfs. dracut does it also. The symlinking was thought as speed gain by jbailey, but I'm less then conviced it is worth it. Also specify to cpio that the files should be owned by root. In retrospect this really similar quasi a fowarded ported patch by Michal Schmidt <xschmi00@stud.feec.vutbr.cz> Closes: #338405, #506540 Signed-off-by: maximilian attems <max@stro.at> Tested-by: Benedikt Spranger <b.spranger@linutronix.de> Reviewed-by: Michael Prokop <mika@debian.org>
536 lines
14 KiB
Bash
536 lines
14 KiB
Bash
# -*- shell-script -*-
|
|
|
|
catenate_cpiogz() {
|
|
# Sanity check
|
|
if [ ! -e "${1}" ]; then
|
|
echo "W: catenate_cpiogz: arg1='${1}' does not exist." >&2
|
|
return
|
|
fi
|
|
|
|
cat "${1}" >>"${__TMPCPIOGZ}"
|
|
}
|
|
|
|
force_load()
|
|
{
|
|
manual_add_modules ${@}
|
|
echo "${@}" >>"${DESTDIR}/conf/modules"
|
|
}
|
|
|
|
# Takes a file containing a list of modules to be added as an
|
|
# argument, figures out dependancies, and adds them.
|
|
#
|
|
# Input file syntax:
|
|
#
|
|
# # comment
|
|
# modprobe_module_name [args ...]
|
|
# [...]
|
|
#
|
|
add_modules_from_file()
|
|
{
|
|
# Sanity check
|
|
if [ ! -e "${1}" ]; then
|
|
echo "W: add_modules_from_file: arg1='${1}' does not exist." >&2
|
|
return
|
|
fi
|
|
|
|
grep '^[^#]' ${1} | while read module args; do
|
|
[ -n "$module" ] || continue
|
|
force_load "${module}" "${args}"
|
|
done
|
|
}
|
|
|
|
# Add dependent modules + eventual firmware
|
|
manual_add_modules()
|
|
{
|
|
local kmod firmware
|
|
|
|
for kmod in $(modprobe --set-version="${version}" --ignore-install \
|
|
--quiet --show-depends "${1}" | awk '/^insmod/ { print $2 }'); do
|
|
# Prune duplicates
|
|
if [ -e "${DESTDIR}/${kmod}" ]; then
|
|
continue
|
|
fi
|
|
|
|
mkdir -p "${DESTDIR}/$(dirname "${kmod}")"
|
|
cp -pL "${kmod}" "${DESTDIR}/$(dirname "${kmod}")"
|
|
if [ "${verbose}" = "y" ]; then
|
|
echo "Adding module ${kmod}"
|
|
fi
|
|
|
|
# Add required firmware
|
|
for firmware in $(modinfo -F firmware "${kmod}"); do
|
|
if [ -e "${DESTDIR}/lib/firmware/${firmware}" ] \
|
|
|| [ -e "${DESTDIR}/lib/firmware/${version}/${firmware}" ]; then
|
|
continue
|
|
fi
|
|
|
|
# Only print warning for missing fw of loaded module
|
|
# or forced loaded module
|
|
if [ ! -e "/lib/firmware/${firmware}" ] \
|
|
&& [ ! -e "/lib/firmware/${version}/${firmware}" ] ; then
|
|
# Only warn about missing firmware if
|
|
# /proc/modules exists
|
|
if [ ! -e /proc/modules ] ; then
|
|
continue
|
|
fi
|
|
|
|
if grep -q "^$(basename "${kmod}" .ko)[[:space:]]" \
|
|
/proc/modules \
|
|
|| grep -q "^$(basename "${kmod}" .ko)" \
|
|
"${CONFDIR}/modules"; then
|
|
echo "W: Possible missing firmware /lib/firmware/${firmware} for module $(basename ${kmod} .ko)" >&2
|
|
fi
|
|
continue
|
|
fi
|
|
|
|
if [ ! -e "${DESTDIR}/lib/udev/firmware.agent" ] \
|
|
&& [ -e "/lib/udev/firmware.agent" ]; then
|
|
copy_exec /lib/udev/firmware.agent
|
|
fi
|
|
|
|
if [ -e "/lib/firmware/${version}/${firmware}" ]; then
|
|
copy_exec "/lib/firmware/${version}/${firmware}"
|
|
else
|
|
copy_exec "/lib/firmware/${firmware}"
|
|
fi
|
|
if [ "${verbose}" = "y" ]; then
|
|
echo "Adding firmware ${firmware}"
|
|
fi
|
|
done
|
|
done
|
|
}
|
|
|
|
# $1 = file to copy to ramdisk
|
|
# $2 (optional) Name for the file on the ramdisk
|
|
# Location of the image dir is assumed to be $DESTDIR
|
|
# We never overwrite the target if it exists.
|
|
copy_exec() {
|
|
local src target x nonoptlib
|
|
local libname dirname
|
|
|
|
src="${1}"
|
|
target="${2:-$1}"
|
|
|
|
[ -f "${src}" ] || return 1
|
|
|
|
if [ -d "${DESTDIR}/${target}" ]; then
|
|
# check if already copied
|
|
[ -e "${DESTDIR}/$target/${src##*/}" ] && return 0
|
|
else
|
|
[ -e "${DESTDIR}/$target" ] && return 0
|
|
#FIXME: inst_dir
|
|
mkdir -p "${DESTDIR}/${target%/*}"
|
|
fi
|
|
|
|
[ "${verbose}" = "y" ] && echo "Adding binary ${src}"
|
|
cp -pL "${src}" "${DESTDIR}/${target}"
|
|
|
|
# Copy the dependant libraries
|
|
for x in $(ldd ${src} 2>/dev/null | sed -e '
|
|
/\//!d;
|
|
/linux-gate/d;
|
|
/=>/ {s/.*=>[[:blank:]]*\([^[:blank:]]*\).*/\1/};
|
|
s/[[:blank:]]*\([^[:blank:]]*\) (.*)/\1/' 2>/dev/null); do
|
|
|
|
# Try to use non-optimised libraries where possible.
|
|
# We assume that all HWCAP libraries will be in tls,
|
|
# sse2, vfp or neon.
|
|
nonoptlib=$(echo "${x}" | sed -e 's#/lib/\(tls\|i686\|sse2\|neon\|vfp\).*/\(lib.*\)#/lib/\2#')
|
|
|
|
if [ -e "${nonoptlib}" ]; then
|
|
x="${nonoptlib}"
|
|
fi
|
|
|
|
libname=$(basename "${x}")
|
|
dirname=$(dirname "${x}")
|
|
|
|
# FIXME inst_lib
|
|
mkdir -p "${DESTDIR}/${dirname}"
|
|
if [ ! -e "${DESTDIR}/${dirname}/${libname}" ]; then
|
|
cp -pL "${x}" "${DESTDIR}/${dirname}"
|
|
[ "${verbose}" = "y" ] && echo "Adding library ${x}" || true
|
|
fi
|
|
done
|
|
}
|
|
|
|
# Copy entire subtrees to the initramfs
|
|
copy_modules_dir()
|
|
{
|
|
local kmod exclude
|
|
local dir="$1"
|
|
shift
|
|
|
|
if ! [ -d "${MODULESDIR}/${dir}" ]; then
|
|
return;
|
|
fi
|
|
if [ "${verbose}" = "y" ]; then
|
|
echo "Copying module directory ${dir}"
|
|
if [ $# -ge 1 ]; then
|
|
echo "(excluding $*)"
|
|
fi
|
|
fi
|
|
while [ $# -ge 1 ]; do
|
|
exclude="${exclude:-} -name $1 -prune -o "
|
|
shift
|
|
done
|
|
for kmod in $(find "${MODULESDIR}/${dir}" ${exclude:-} -name '*.ko' -print); do
|
|
manual_add_modules $(basename ${kmod} .ko)
|
|
done
|
|
}
|
|
|
|
# walk /sys for relevant modules
|
|
sys_walk_mod_add()
|
|
{
|
|
local driver_path module
|
|
device_path="$1"
|
|
|
|
while [ "${device_path}" != "/sys" ]; do
|
|
sys_walk_modalias ${device_path}
|
|
driver_path="$(readlink -f ${device_path}/driver/module)"
|
|
if [ -e "$driver_path" ]; then
|
|
module="$(basename $(readlink -f $driver_path))"
|
|
if [ -n "${module}" ]; then
|
|
force_load "${module}"
|
|
fi
|
|
fi
|
|
device_path="$(dirname ${device_path})"
|
|
done
|
|
}
|
|
|
|
# walk /sys for relevant modalias
|
|
sys_walk_modalias()
|
|
{
|
|
local device_path modalias
|
|
|
|
device_path="$(dirname "${1}")"
|
|
device_path="$(dirname "${device_path}")"
|
|
if [ -e "${device_path}/modalias" ]; then
|
|
modalias=$(cat "${device_path}/modalias")
|
|
fi
|
|
|
|
if [ -n "${modalias}" ]; then
|
|
force_load "${modalias}"
|
|
fi
|
|
}
|
|
|
|
# find and only copy root relevant modules
|
|
dep_add_modules()
|
|
{
|
|
local block minor root FSTYPE root_dev_path x
|
|
|
|
# require mounted sysfs
|
|
if [ ! -d /sys/devices/ ]; then
|
|
echo "mkinitramfs: MODULES dep requires mounted sysfs on /sys" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# findout root block device + fstype
|
|
eval "$(mount | awk '/\/dev\// {if ($3 == "/") {print "root=" $1 "\nFSTYPE=" $5; exit}}')"
|
|
|
|
# On failure fallback to /proc/mounts if readable
|
|
if [ -z "$root" ] && [ -r /proc/mounts ]; then
|
|
eval "$(awk '!/^rootfs / {if ($2 == "/") {print "root=" $1 "\nFSTYPE=" $3; exit}}' /proc/mounts)"
|
|
fi
|
|
|
|
# recheck root device
|
|
if [ -z "$root" ]; then
|
|
echo "mkinitramfs: failed to determine root device" >&2
|
|
echo "mkinitramfs: workaround is MODULES=most, check:" >&2
|
|
echo "grep -r MODULES /etc/initramfs-tools/" >&2
|
|
echo "" >&2
|
|
echo "Error please report bug on initramfs-tools" >&2
|
|
echo "Include the output of 'mount' and 'cat /proc/mounts'" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# handle ubifs and return since ubifs root is a char device but
|
|
# most of the commands below only work with block devices.
|
|
if [ "${FSTYPE}" = "ubifs" ]; then
|
|
manual_add_modules "${FSTYPE}"
|
|
return
|
|
fi
|
|
|
|
if [ "${root}" = "/dev/root" ] ; then
|
|
root="/dev/disk/by-uuid/"$(blkid -o value -s UUID ${root}) 2>/dev/null
|
|
fi
|
|
root="$(readlink -f ${root})"
|
|
|
|
# do not trust mount, check superblock
|
|
eval "$(/usr/lib/klibc/bin/fstype ${root})"
|
|
|
|
# check that fstype rootfs recognition
|
|
if [ "${FSTYPE}" = "unknown" ]; then
|
|
FSTYPE=$(blkid -o value -s TYPE "${root}")
|
|
if [ -z "${FSTYPE}" ]; then
|
|
echo "mkinitramfs: unknown fstype on root ${root}" >&2
|
|
echo "mkinitramfs: workaround is MODULES=most" >&2
|
|
echo "Error please report bug on initramfs-tools" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Add rootfs
|
|
manual_add_modules "${FSTYPE}"
|
|
|
|
# lvm or luks root
|
|
if [ "${root#/dev/mapper/}" != "${root}" ] \
|
|
|| [ "${root#/dev/dm-}" != "${root}" ]; then
|
|
minor=$((0x$(stat --format "%T" ${root}) % 256))
|
|
block=$(ls -1 /sys/block/dm-${minor}/slaves | head -n 1)
|
|
# lvm on luks or luks on lvm, possibly lvm snapshots
|
|
while [ "${block#dm-}" != "${block}" ]; do
|
|
block=$(ls -1 /sys/block/${block}/slaves | head -n 1)
|
|
done
|
|
# lvm on md or luks on md
|
|
if [ "${block#md}" != "${block}" ]; then
|
|
block=$(sed -ne 's/multipath/[/' -e 's/linear/[/' -e 's/raid[0-9][0-9]*/[/' -e 's/\([hs]d[a-z][a-z]*\)[0-9][0-9]*/\1/g' -e '/^'${block}' :/s/^[^[]*\[ \([^\[]*\)\[.*$/\1/p' </proc/mdstat)
|
|
fi
|
|
# luks or lvm on cciss or ida
|
|
if [ "${block#cciss}" != "${block}" ] \
|
|
|| [ "${block#ida}" != "${block}" ]; then
|
|
block="${block%p*}"
|
|
else
|
|
block=${block%%[0-9]*}
|
|
fi
|
|
# md root new naming scheme /dev/md/X
|
|
elif [ "${root#/dev/md/}" != "${root}" ]; then
|
|
root=${root#/dev/md/}
|
|
# strip partion number
|
|
root=${root%%p[0-9]*}
|
|
# drop the partition number only for sdX and hdX devices
|
|
# and keep it for other devices like loop#, dm-# devices
|
|
block=$(sed -ne 's/multipath/[/' -e 's/linear/[/' -e 's/raid[0-9][0-9]*/[/' -e 's/\([hs]d[a-z][a-z]*\)[0-9][0-9]*/\1/g' -e '/^md'$root' :/s/^[^[]*\[ \([^\[]*\)\[.*$/\1/p' </proc/mdstat)
|
|
# md root /dev/mdX
|
|
elif [ "${root#/dev/md}" != "${root}" ]; then
|
|
root=${root#/dev/md}
|
|
# strip partion number
|
|
root=${root%%p[0-9]*}
|
|
# drop the partition number only for sdX and hdX devices
|
|
# and keep it for other devices like loop#, dm-# devices
|
|
block=$(sed -ne 's/multipath/[/' -e 's/linear/[/' -e 's/raid[0-9][0-9]*/[/' -e 's/\([hs]d[a-z][a-z]*\)[0-9][0-9]*/\1/g' -e '/^md'$root' :/s/^[^[]*\[ \([^\[]*\)\[.*$/\1/p' </proc/mdstat)
|
|
# cciss device
|
|
elif [ "${root#/dev/cciss/}" != "${root}" ]; then
|
|
block=${root#/dev/cciss/*}
|
|
block="cciss!${block%p*}"
|
|
# ida device
|
|
elif [ "${root#/dev/ida/}" != "${root}" ]; then
|
|
block=${root#/dev/ida/*}
|
|
block="ida!${block%p*}"
|
|
# loop root /dev/loopX
|
|
elif [ "${root#/dev/loop}" != "${root}" ]; then
|
|
root=${root#/dev/}
|
|
block=$(losetup -a \
|
|
| awk "/${root}/{print substr(\$3, 7, 3); exit}")
|
|
# Xen virtual device /dev/xvdX
|
|
elif [ "${root#/dev/xvd}" != "${root}" ]; then
|
|
block=${root#/dev/}
|
|
# Xen has a mode where only the individual partitions are
|
|
# registered with the kernel as well as the usual full disk
|
|
# with partition table scheme.
|
|
if [ ! -e /sys/block/${block} ] ; then
|
|
block=${block%%[0-9]*}
|
|
fi
|
|
# mmc root /dev/mmcblkXpX
|
|
elif [ "${root#/dev/mmcblk}" != "${root}" ]; then
|
|
block=${root#/dev/}
|
|
block=${block%%p[0-9]*}
|
|
|
|
# DAC960 - good old mylex raid - root dev format /dev/rd/cXdXpX
|
|
elif [ "${root#/dev/rd/c}" != "${root}" ]; then
|
|
block="rd!c${root#/dev/rd/c}"
|
|
block=${block%%p[0-9]*}
|
|
|
|
# etherd device
|
|
elif [ "${root#/dev/etherd/}" != "${root}" ]; then
|
|
block=${root#/dev/etherd/*}
|
|
block="etherd!${block%p*}"
|
|
# classical root device
|
|
else
|
|
block=${root#/dev/}
|
|
block=${block%%[0-9]*}
|
|
fi
|
|
|
|
# Error out if /sys lack block dev
|
|
if [ -z "${block}" ] || [ ! -e /sys/block/${block} ]; then
|
|
echo "mkinitramfs: for root ${root} missing ${block} /sys/block/ entry" >&2
|
|
echo "mkinitramfs: workaround is MODULES=most" >&2
|
|
echo "mkinitramfs: Error please report the bug" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# sys walk ATA
|
|
root_dev_path=$(readlink -f /sys/block/${block}/device)
|
|
sys_walk_mod_add ${root_dev_path}
|
|
|
|
# catch old-style IDE
|
|
if [ -d "${DESTDIR}/lib/modules/${version}/kernel/drivers/ide" ]; then
|
|
sys_walk_modalias ${root_dev_path}
|
|
manual_add_modules ide-gd_mod
|
|
manual_add_modules ide-cd
|
|
fi
|
|
|
|
if [ -d "${DESTDIR}/lib/modules/${version}/kernel/drivers/scsi" ]; then
|
|
manual_add_modules sd_mod
|
|
fi
|
|
|
|
if [ -e /sys/bus/mmc/devices/ ]; then
|
|
manual_add_modules mmc_block
|
|
fi
|
|
|
|
if [ -e /sys/bus/virtio ] ; then
|
|
manual_add_modules virtio_pci
|
|
fi
|
|
|
|
if [ -e /sys/bus/i2o/devices/ ]; then
|
|
force_load i2o_block
|
|
force_load i2o_config
|
|
fi
|
|
|
|
if [ -e /sys/bus/ps3_system_bus/ ]; then
|
|
for x in ps3disk ps3rom ps3-gelic ps3_sys_manager; do
|
|
manual_add_modules "${x}"
|
|
done
|
|
fi
|
|
|
|
if [ -e /sys/bus/vio/ ]; then
|
|
for x in sunvnet sunvdc; do
|
|
manual_add_modules "${x}"
|
|
done
|
|
fi
|
|
}
|
|
|
|
|
|
# The modules "most" classes added per default to the initramfs
|
|
auto_add_modules()
|
|
{
|
|
case "${1:-}" in
|
|
base)
|
|
for x in ehci-hcd ohci-hcd uhci-hcd usbhid xhci hid-apple \
|
|
hid-cherry hid-logitech hid-microsoft hid-sunplus \
|
|
btrfs ext2 ext3 ext4 ext4dev isofs jfs nfs reiserfs udf xfs \
|
|
af_packet atkbd i8042 virtio_pci; do
|
|
manual_add_modules "${x}"
|
|
done
|
|
;;
|
|
net)
|
|
copy_modules_dir kernel/drivers/net \
|
|
appletalk arcnet bonding can hamradio irda pcmcia \
|
|
tokenring usb wan wimax wireless
|
|
;;
|
|
ide)
|
|
copy_modules_dir kernel/drivers/ide
|
|
;;
|
|
mmc)
|
|
copy_modules_dir kernel/drivers/mmc
|
|
;;
|
|
scsi)
|
|
copy_modules_dir kernel/drivers/scsi
|
|
for x in mptfc mptsas mptscsih mptspi zfcp; do
|
|
manual_add_modules "${x}"
|
|
done
|
|
;;
|
|
ata)
|
|
copy_modules_dir kernel/drivers/ata
|
|
;;
|
|
block)
|
|
copy_modules_dir kernel/drivers/block
|
|
;;
|
|
ubi)
|
|
for x in deflate zlib lzo ubi ubifs; do
|
|
manual_add_modules "${x}"
|
|
done
|
|
;;
|
|
ieee1394)
|
|
for x in ohci1394 sbp2; do
|
|
manual_add_modules "${x}"
|
|
done
|
|
;;
|
|
firewire)
|
|
for x in firewire-ohci firewire-sbp2; do
|
|
manual_add_modules "${x}"
|
|
done
|
|
;;
|
|
i2o)
|
|
for x in i2o_block; do
|
|
manual_add_modules "${x}"
|
|
done
|
|
;;
|
|
dasd)
|
|
for x in dasd_diag_mod dasd_eckd_mod dasd_fba_mod; do
|
|
manual_add_modules "${x}"
|
|
done
|
|
;;
|
|
usb_storage)
|
|
copy_modules_dir kernel/drivers/usb/storage
|
|
;;
|
|
*)
|
|
auto_add_modules base
|
|
auto_add_modules net
|
|
auto_add_modules ide
|
|
auto_add_modules scsi
|
|
auto_add_modules block
|
|
auto_add_modules ata
|
|
auto_add_modules i2o
|
|
auto_add_modules dasd
|
|
auto_add_modules ieee1394
|
|
auto_add_modules firewire
|
|
auto_add_modules mmc
|
|
auto_add_modules usb_storage
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# 'depmod' only looks at symbol dependencies; there is no way for
|
|
# modules to declare explicit dependencies through module information,
|
|
# so dependencies on e.g. crypto providers are hidden. Until this is
|
|
# fixed, we need to handle those hidden dependencies.
|
|
hidden_dep_add_modules()
|
|
{
|
|
for dep in "lib/libcrc32c crc32c" "fs/ubifs/ubifs deflate zlib lzo"; do
|
|
set -- $dep
|
|
if [ -f "${DESTDIR}/lib/modules/${version}/kernel/$1.ko" ]; then
|
|
shift
|
|
for i in "$@" ; do
|
|
manual_add_modules "$i"
|
|
shift
|
|
done
|
|
fi
|
|
done
|
|
}
|
|
|
|
# mkinitramfs help message
|
|
usage()
|
|
{
|
|
cat >&2 << EOF
|
|
|
|
Usage: ${0} [OPTION]... -o outfile [version]
|
|
|
|
Options:
|
|
-c compress Override COMPRESS setting in initramfs.conf.
|
|
-d confdir Specify an alternative configuration directory.
|
|
-k Keep temporary directory used to make the image.
|
|
-o outfile Write to outfile.
|
|
-r root Override ROOT setting in initramfs.conf.
|
|
|
|
See mkinitramfs(8) for further details.
|
|
EOF
|
|
exit 1
|
|
|
|
}
|
|
|
|
# cache boot scripts order
|
|
cache_run_scripts()
|
|
{
|
|
DESTDIR=${1}
|
|
scriptdir=${2}
|
|
initdir=${DESTDIR}${scriptdir}
|
|
[ ! -d ${initdir} ] && return
|
|
|
|
runlist=$(get_prereq_pairs | tsort)
|
|
for crs_x in ${runlist}; do
|
|
[ -f ${initdir}/${crs_x} ] || continue
|
|
echo "${scriptdir}/${crs_x}" >> ${initdir}/ORDER
|
|
echo "[ -e /conf/param.conf ] && . /conf/param.conf" >> ${initdir}/ORDER
|
|
done
|
|
}
|