#!/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 comarpisons # #TODO trap and remove FILELIST # Settings BASEDIR="" FILELIST="$(mktemp /tmp/.tmpfilelist.XXXX)" KERNELVERSION="$(uname -r)" FUNCTIONS="functions" CONFIG="mkinitcpio.conf" HOOKDIR="hooks" INSTDIR="install" MODULE_FILE="" SAVELIST="" GENIMG="" APPEND="" PRESET="" PRESETDIR="mkinitcpio.d" QUIET="y" SHOW_AUTOMODS="n" APPNAME=$(basename "${0}") usage () { echo "${APPNAME}: usage" echo " -c CONFIG Use CONFIG file. default: /etc/mkinitcpio.conf" echo " -k KERNELVERSION Use KERNELVERSION. default: $(uname -r)" echo " -s NAME Save filelist. default: no" echo " -b BASEDIR Use BASEDIR. default: /" echo " -g IMAGE Generate a cpio image as IMAGE. default: no" echo " -a NAME Append to an existing filelist. default: no" echo " -p PRESET Build specified preset." echo " -v Verbose output. Default: no" echo " -M Display modules found via autodetection." echo " -L List all available hooks." echo " -H HOOKNAME Output help for hook 'HOOKNAME'." echo " -h This message." exit 1 } while getopts ':c:k:s:b:g:a:p:vH:LMh' arg; do if [ "${OPTARG:0:1}" = "-" ]; then echo "error: optional argument to '-$arg' begins with a '-'" echo " you probably don't want this....aborting." usage fi case "$arg" in c) CONFIG="$OPTARG" ;; k) KERNELVERSION="$OPTARG" ;; s) SAVELIST="y"; FILELIST="$OPTARG" ;; b) BASEDIR="$OPTARG" ;; g) GENIMG="$OPTARG" ;; a) APPEND="y"; SAVELIST="y"; FILELIST="$OPTARG" ;; p) PRESET="$OPTARG" ;; v) QUIET="n" ;; H) source "${INSTDIR}/${OPTARG}"; echo "Help for hook '${OPTARG}':" help exit 0 ;; L) echo "Available hooks: " for h in ${INSTDIR}/*; do echo " $(basename ${h})" done exit 0 ;; M) SHOW_AUTOMODS="y" ;; h|?) usage ;; :) echo "${OPTARG} requires a value..."; usage ;; *) echo "invalid argument '$arg'"; usage ;; esac done shift $(($OPTIND - 1)) # use preset $PRESET if [ -n "${PRESET}" ]; then if [ -f "${PRESETDIR}/${PRESET}.preset" ]; then # Use -b and -v options specified earlier PRESET_MKOPTS="${0}" [ -n "${BASEDIR}" ] && PRESET_MKOPTS="${PRESET_MKOPTS} -b ${BASEDIR}" [ "${QUIET}" = "n" ] && PRESET_MKOPTS="${PRESET_MKOPTS} -v" # Build all images source ${PRESETDIR}/${PRESET}.preset for p in ${PRESETS[@]}; do echo "==> Building image \"${p}\"" PRESET_CMD="${PRESET_MKOPTS}" eval "PRESET_KVER=\"\${${p}_kver}\"" eval "PRESET_CONFIG=\"\${${p}_config}\"" eval "PRESET_IMAGE=\"\${${p}_image}\"" if [ -n "${PRESET_KVER}" ]; then PRESET_CMD="${PRESET_CMD} -k ${PRESET_KVER}" elif [ -n "${ALL_kver}" ]; then PRESET_CMD="${PRESET_CMD} -k ${ALL_kver}" else echo "==> No kernel version specified. Skipping image \"${p}\"." continue fi if [ -n "${PRESET_CONFIG}" ]; then PRESET_CMD="${PRESET_CMD} -c ${PRESET_CONFIG}" else echo "==> No configuration file specified. Skipping image \"${p}\"." continue fi if [ -n "${PRESET_IMAGE}" ]; then PRESET_CMD="${PRESET_CMD} -g ${PRESET_IMAGE}" else echo "==> No image file specified. Skipping image \"${p}\"." continue fi echo "==> Running command: ${PRESET_CMD}" if ${PRESET_CMD}; then echo "==> SUCCESS" else echo "==> FAIL" fi done exit 0 else echo "Preset ${PRESET} does not exist. Exiting." exit 1 fi fi # append a trailing / if needed if [ "${BASEDIR:${#BASEDIR}}" == "/" ]; then BASEDIR="${BASEDIR:0:${#BASEDIR}-1}" fi MODULEDIR="${BASEDIR}/lib/modules/${KERNELVERSION}" if [ "x${BASEDIR}" != "x" ]; then if [ "${BASEDIR:0:1}" != "/" ]; then BASEDIR="$(pwd)/${BASEDIR}" 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 if [ "x${SAVELIST}" == "x" ]; then rm ${FILELIST} touch "${FILELIST}" else echo "destination file list '${FILELIST}' exists - remove before running" exit 1 fi else touch "${FILELIST}" fi BASEDIR=$(echo ${BASEDIR} | tr -s /) MODULEDIR=$(echo ${MODULEDIR} | tr -s /) source "${FUNCTIONS}" if [ "${SHOW_AUTOMODS}" = "y" ]; then echo "Modules autodetected:" source "${INSTDIR}/autodetect" install cat "${MODULE_FILE}" exit 0 fi echo ":: Begin build" #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..."; } # Deprecation check # A hook is considered deprecated if it is a symlink # within $INSTDIR. if [ -L "${INSTDIR}/${hook}" ]; then newhook="$(readlink -ne "${INSTDIR}/${hook}")" if [ -n "${newhook}" -a "${INSTDIR}/$(basename ${newhook})" -ef "${newhook}" ]; then newhook="$(basename ${newhook})" echo " -------------------------------------------------------------------" echo " WARNING: Hook \"${hook}\" is deprecated." echo " Replace it with \"${newhook}\" in your configuration file." echo " -------------------------------------------------------------------" hook="${newhook}" fi fi if grep "install" "${INSTDIR}/${hook}" >/dev/null 2>&1; then source "${INSTDIR}/${hook}" echo ":: Parsing hook [${hook}]" install parse_hook else die "Hook '${hook}' can not be found." fi done if [ "${HAS_MODULES}" == "y" ]; then echo ":: Generating module dependencies" for mod in $(grep "file /lib/modules/${KERNELVERSION}" ${FILELIST} | cut -d' ' -f2); do dir=$(dirname "${mod}") mkdir -p "/tmp/${dir}" cp "${BASEDIR}${mod}" "/tmp/${dir}/" done depmod -b /tmp ${KERNELVERSION} add_file "/tmp/lib/modules/${KERNELVERSION}/modules.dep" "/lib/modules/${KERNELVERSION}/modules.dep" add_file "/tmp/lib/modules/${KERNELVERSION}/modules.alias" "/lib/modules/${KERNELVERSION}/modules.alias" add_file "/tmp/lib/modules/${KERNELVERSION}/modules.symbols" "/lib/modules/${KERNELVERSION}/modules.symbols" fi status=0 if [ "x$GENIMG" != "x" ]; then echo -n ":: Generating image '${GENIMG}'..." if ! gen_init_cpio ${FILELIST} | gzip -9 > "${GENIMG}"; then echo "FAILED" status=1 else echo "SUCCESS" status=0 fi if [ "x${SAVELIST}" == "x" ]; then rm ${FILELIST} fi else echo ":: Dry run complete, use -g IMAGE to generate a real image" fi #cleanup - we should probably trap this... isempty () { [ $(ls -1 "${1}" | wc -l) -eq 0 ]; } [ -e "${MODULE_FILE}" ] && rm "${MODULE_FILE}" if [ -d /tmp/lib/modules/${KERNELVERSION} ]; then rm -rf /tmp/lib/modules/${KERNELVERSION} isempty /tmp/lib/modules && rm -rf /tmp/lib/modules isempty /tmp/lib && rm -rf /tmp/lib fi exit $status #vim:set ft=sh ts=4 sw=4 noet: