#!/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 modprobe --set-version="$KERNEL" --list "$@" 2>/dev/null fi } ListModuleFiles() { modprobe --set-version="$KERNEL" --show-depends \ --ignore-all-commands "$@" 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%.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_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 } 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%.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." #--------------------------------------------------------------- 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" ) > "$TEMPLATE" if [ -n "$OUTPUT" ]; then gencpio "$TEMPLATE" |gzip -c > "$OUTPUT" else gencpio "$TEMPLATE" |gzip -c fi Exit 0