diff options
author | Aaron Griffin <aaron@archlinux.org> | 2006-04-20 21:17:22 +0200 |
---|---|---|
committer | Aaron Griffin <aaron@archlinux.org> | 2006-04-20 21:17:22 +0200 |
commit | fb2046ba69906fc3c019cebb12e33f645eafefd1 (patch) | |
tree | 0b8f0ce9ea3520c8b107513546b40975b1613ad3 /mkinitcpio | |
download | mkinitcpio-fb2046ba69906fc3c019cebb12e33f645eafefd1.tar.gz mkinitcpio-fb2046ba69906fc3c019cebb12e33f645eafefd1.tar.xz |
Just importing everything I have available - home connection is down ATM
git-svn-id: http://projects.archlinux.org/svn/initramfs/mkinitcpio@2 880c04e9-e011-0410-abf7-b926e227c9cd
Diffstat (limited to 'mkinitcpio')
-rw-r--r-- | mkinitcpio | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/mkinitcpio b/mkinitcpio new file mode 100644 index 0000000..50d3647 --- /dev/null +++ b/mkinitcpio @@ -0,0 +1,253 @@ +#!/bin/sh +# mkinitcpio - modular tool for building an init ramfs cpio image +# +# IMPORTANT: We need to keep a common base syntax here +# because some of these hooks/scripts need to run under +# the klibc shell or even busybox's ash - therefore, the +# following constraints should be enforced: +# variables should be quoted and bracketed "${SOMEVAR}" +# inline execution should be done with $() instead of backticks +# use "x${var}" = "x" to test for nulls/empty strings +# incase of embedded spaces, quote all path names and string comaprissons +# +# TODO +# sudo cp img /boot + +HOOKDIR="hooks" + +# Settings +BASEDIR="" +KERNELVERSION="$(uname -r)" +CONFIG="mkinitcpio.conf" +SAVELIST="" +GENIMG="" +APPEND="" + +usage () +{ + echo "TODO usage..." + exit 1 +} + +while getopts 'c:k:sb:g:a' arg; do + case "$arg" in + c) CONFIG="$OPTARG" ;; + k) KERNELVERSION="$OPTARG" ;; + s) SAVELIST="y" ;; + b) BASEDIR="$OPTARG" ;; + g) GENIMG="$OPTARG" ;; + a) APPEND="y" ;; + ?) usage ;; + *) echo "invalid argument '$arg'"; usage ;; + esac +done +shift $(($OPTIND - 1)) + +# append a trailing / if needed +if [ "${BASEDIR:${#BASEDIR}}" == "/" ]; then + BASEDIR="${BASEDIR:0:${#BASEDIR}-1}" +fi + +MODULEDIR="${BASEDIR}/lib/modules/${KERNELVERSION}" +FILELIST=${1:-"initcpio.filelist"} + +if [ "x${BASEDIR}" != "x" ]; then + if [ "${BASEDIR:0:1}" != "/" ]; then + echo "base directory '${BASEDIR}' must be an absolute path" + exit 1 + elif [ ! -d "${BASEDIR}" ]; then + echo "base directory '${BASEDIR}' does not exist or is not a directory" + exit 1 + fi +fi + +if [ ! -f "${CONFIG}" ]; then + echo "config file '${CONFIG}' cannot be found, aborting..." + exit 1 +fi +source "${CONFIG}" + +if [ -f "${FILELIST}" -a "x${APPEND}" == "x" ]; then + echo "destination file list '${FILELIST}' exists - remove before running" + exit 1 +elif [ -f "${DESTIMG}" ]; then + echo "destination image '${DESTIMG}' exists - remove before running" + exit 1 +else + touch "${FILELIST}" +fi + +# this function is a helper for the *-auto install functions +auto_modules () +{ + aliases=$(find /sys/devices/ -name modalias -exec cat {} \;) + modprobe --show-depends -a $aliases 2>/dev/null |\ + sed "s|insmod \(.*\)|\1|" | sort -u +} + +add_dir() +{ + local dir + dir="${1}" + if [ "x${dir}" != "x" -a "${dir}" != "/" ]; then + dir="${dir}" #this got stripped off above... put it back + + if ! grep "dir ${dir} " "${FILELIST}" 2>&1 > /dev/null; then + add_dir $(dirname ${dir}) + echo " adding dir ${dir}" + echo "dir ${dir} 755 0 0" >> "${FILELIST}" + fi + fi +} + +add_symlink () +{ + local fil dest dir + if [ -L ${1} ]; then + fil="${1}" + dest="${fil##$BASEDIR}" + dir=$(dirname "${dest}") + add_dir "${dir}" + if ! grep "slink ${fil} " "${FILELIST}" 2>&1 > /dev/null; then + echo " adding symlink ${dest}" + echo "slink ${dest} ${fil} $(stat -c '%a %u %g' ${fil})" >> "${FILELIST}" + fi + fi +} + +add_file () +{ + local fil lnk dir dest + if [ -e "${1}" ]; then + fil="${1}" + lnk=$(readlink -f "${fil}") + if [ -n "${lnk}" ]; then + add_symlink "${fil}" + fil="${lnk}" + fi + if [ $# -eq 2 ]; then + dest="${2}" + else + dest="${fil##$BASEDIR}" + fi + + dir=$(dirname "${dest}") + add_dir "${dir}" + + if ! grep "file ${fil} " "${FILELIST}" 2>&1 > /dev/null; then + echo " adding file ${dest}" + echo "file ${dest} ${fil} $(stat -c '%a %u %g' ${fil})" >> "${FILELIST}" + fi + fi +} + +HAS_MODULES="n" +add_module() +{ + local fil path mod deps + #cleanup - remove .ko, replace - and _ with [-_] to match either + fil=$(basename "${1}" | sed -e "s|[-_]|\[-_\]|g" -e "s|\.ko$||g") + + for path in $(find "${MODULEDIR}" -type f -name "${fil}.ko"); do + for mod in $(modinfo -F depends "${path}" | tr ',' ' '); do + if [ "x${mod}" != "x" ]; then + add_module "${mod}" + HAS_MODULES="y" + fi + done + add_file "${path}" + done +} + +add_binary() +{ + local bin type lib + bin=$(which "${1}") + if [ $? -ne 0 ]; then + bin="${1}" + fi + + if [ ! -f "${bin}" ]; then + echo "add_binary: '${bin}' is not a file" + return 1 + fi + + if [ $? -eq 0 ]; then + type=$(file -b "${bin}") + case "${type}" in + *script*) + msg " adding '${type}' script, ensure proper interp exists..." + add_file "${bin}" + ;; + *executable*) + add_file "${bin}" + #note, this will also handle 'not a dynamic executable' spit out by + # static binaries... the deps will produce nothing + for lib in $(ldd ${bin} 2>/dev/null | sed "s|.*=>\(.*\)|\1|"); do + if [ "x${lib}" != "x" ]; then + #remove TLS libraries + notls=$(echo ${lib} | sed 's|/lib/tls.*/\(lib.*\)|/lib/\1|') + [ -e "${notls}" ] && lib="${notls}" + [ -f "${lib}" ] && add_file "${lib}" + fi + done + ;; + *) + echo "add_binary: unknown type '${type}' for binary '${bin}'" + return 1 + ;; + esac + fi +} + +function parse_hook() +{ + local mod bin fil + for mod in $MODULES; do + if [ "x${mod}" != "x" ]; then + add_module "${mod}" + fi + done + + for bin in $BINARIES; do + if [ "x${bin}" != "x" ]; then + add_binary "${bin}" + fi + done + + for fil in $FILES; do + if [ "x${fil}" != "x" ]; then + add_file "${fil}" + fi + done +} + +#parse 'global' hook, as defined in ${CONFIG} +parse_hook + +for hook in $HOOKS; do + unset MODULES + unset BINARIES + unset FILES + install () { msg "$hook: no install function..."; } + source "${HOOKDIR}/${hook}" + install + parse_hook + #quick test to check for existance... need a better way... + if grep "run_hook" "${HOOKDIR}/${hook}" 2>&1>/dev/null; then + add_file "${HOOKDIR}/${hook}" "/hooks/${hook}" + fi +done + +if [ "${HAS_MODULES}" == "y" ]; then + add_file "${MODULEDIR}/modules.dep" + add_file "${MODULEDIR}/modules.alias" + add_file "${MODULEDIR}/modules.symbols" +fi + +if [ "x$GENIMG" != "x" ]; then + gen_init_cpio ${FILELIST} | gzip -9 > "${GENIMG}" + if [ "x${SAVELIST}" == "x" ]; then + rm ${FILELIST} + fi +fi |