#!/bin/sh PROG=mkmodpack VERSION=0.1 CATCHED= Exit() { local rc=$? [ -z "$1" ] || rc="$1" CATCHED=1 exit $rc } Warning() { echo "$PROG: warning: $*" >&2 } Fatal() { echo "$PROG: $*" >&2 Exit 1 } KERNEL= OUTPUT= WORKDIR= TEMPLATE= pattern= uname_r="$(uname -r)" exit_handler() { local rc=$? trap - EXIT [ -n "$CATCHED" -o $rc -eq 0 ] || echo "$PROG: unhandled error, exiting..." [ -z "$WORKDIR" ] || rm -rf "$WORKDIR" [ -z "$TEMPLATE" ] || rm -f "$TEMPLATE" exit $rc } signal_handler() { echo 'Interrupted!' >&2 Exit 1 } trap exit_handler EXIT trap signal_handler SIGHUP SIGPIPE SIGINT SIGTERM SIGQUIT FIRMWARE_DIRS="/lib/firmware /usr/lib/hotplug/firmware" Usage() { cat >&2 </dev/null |grep -wf "$pattern" else find /lib/modules/$KERNEL -type f 2>/dev/null fi } ListModuleFiles() { modprobe --set-version="$KERNEL" --show-depends "$@" 2>/dev/null } AddUniqueModule() { local path="$1" modules= modules="$MODULES $path" modules="$(echo "$modules" |sort)" if [ -z "$(echo "$modules" |uniq -d)" ]; then echo "$modules" fi } AddModuleFile() { local path="$1" name="$1" modules= name="${name##*/}" name="${name%.gz}" name="${name%.xz}" name="${name%.ko}" modules=$(AddUniqueModule "$path") if [ -n "$modules" ]; then MODULES="$modules" AddModuleFirmware "$name" "$path" fi } AddModuleFirmware() { local mod_name="$1" && shift local mod_path="$1" && shift local fw_list fw_name fw_dir fw_file fw_privdir fw_list="$(modinfo -F firmware "$mod_path")" || return [ -n "$fw_list" ] || return for fw_name in $fw_list; do fw_file= for fw_dir in $FIRMWARE_DIRS; do if [ -r "$fw_dir/$fw_name" ]; then fw_file="$fw_dir/$fw_name" break fi done [ -n "$fw_file" ] || { Warning "Firmware file \"$fw_name\" for module \"$mod_name\" not found" continue } fw_privdir=$fw_name while [ ! "$fw_privdir" = "${fw_name%%/*}" ]; do fw_privdir="${fw_privdir%/*}" FILES="$FILES dir /lib/firmware/$fw_privdir 0755 0 0" done FILES="$FILES file /lib/firmware/$fw_name $fw_file 0644 0 0" done } AddModule() { local path="$1" name="$1" m list name="${name##*/}" name="${name%.gz}" name="${name%.xz}" name="${name%.ko}" list=`ListModuleFiles "$name"` for m in $list; do [ -z "${m##/lib/modules/*}" ] || continue AddModuleFile "$m" done } TEMP=`getopt -n "$0" -o k:,o:,p:,h -l kernel:,output:,pattern:,help,version -- "$@"` || exit 1 eval set -- "$TEMP" while :; do case "$1" in -k|--kernel) shift KERNEL="$1" ;; -o|--output) shift OUTPUT="$1" ;; -p|--pattern*) shift pattern="$1" ;; -h|--help) Usage 0 ;; --version) echo "$PROG: version $VERSION" exit 0 ;; --) shift; break ;; *) Fatal "Unrecognized option: $1" ;; esac shift done [ -n "$KERNEL" ] || KERNEL="$uname_r" [ -d "/lib/modules/$KERNEL" ] || Fatal "Directory /lib/modules/$KERNEL does not exists." # modprobe from kmod-9+ *requires* modules.dep.bin (ALT #27640) if [ ! -f /lib/modules/$KERNEL/modules.dep.bin ]; then depmod -a -F "/boot/System.map-$KERNEL" "$KERNEL" || Fatal "Failed to create modules dependencies (full)." fi #--------------------------------------------------------------- FIRMWARE_DIRS="$FIRMWARE_DIRS /lib/firmware/$KERNEL" MODULES= FILES= for m in $(ListModules); do AddModule "$m" done WORKDIR=`mktemp -td mkmodpack.XXXXXXXXXX` || Fatal "Failed to create working directory." TEMPLATE=`mktemp -t mkmodpack.XXXXXXXXXX` || Fatal "Failed to create temporary file." echo "$MODULES" |cpio -pmd "$WORKDIR" 2>/dev/null || Fatal "Failed to copy modules to working directory." depmod -a -F "/boot/System.map-$KERNEL" -b "$WORKDIR" "$KERNEL" || Fatal "Failed to create modules dependencies." ( cd "$WORKDIR" find "lib/modules/$KERNEL" -type d |sed -e 's,^.\+$,dir\t/&\t0755\t0 0,g' find "lib/modules/$KERNEL" -type f |sed -e "s,^.\+$,file\t/&\t$WORKDIR/&\t0644\t0 0,g" echo "$FILES"|sort -k2|uniq ) > "$TEMPLATE" if [ -n "$OUTPUT" ]; then gencpio "$TEMPLATE" |gzip -c > "$OUTPUT" else gencpio "$TEMPLATE" |gzip -c fi if [ -s "$pattern" ]; then for m in `grep -v '#' "$pattern" | sort -u`; do name="${m##*/}" name="${name%.gz}" name="${name%.xz}" name="${name%.ko}" # Omit built-in modules whose names match in modprobe output and in "pattern" ListModuleFiles "$name" | grep "builtin" | grep -q "$name" 2>/dev/null && continue echo "$MODULES" | grep -qw "$m" 2>/dev/null || Warning "Module pattern \"$m\" doesn't match anything." done fi Exit 0