Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/sh
0002 # Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org>
0003 # Copyright (C) 2006 Sam Ravnborg <sam@ravnborg.org>
0004 #
0005 # Released under the terms of the GNU GPL
0006 #
0007 # Generate a cpio packed initramfs. It uses gen_init_cpio to generate
0008 # the cpio archive.
0009 # This script assumes that gen_init_cpio is located in usr/ directory
0010 
0011 # error out on errors
0012 set -e
0013 
0014 usage() {
0015 cat << EOF
0016 Usage:
0017 $0 [-o <file>] [-l <dep_list>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ...
0018         -o <file>      Create initramfs file named <file> by using gen_init_cpio
0019         -l <dep_list>  Create dependency list named <dep_list>
0020         -u <uid>       User ID to map to user ID 0 (root).
0021                        <uid> is only meaningful if <cpio_source> is a
0022                        directory.  "squash" forces all files to uid 0.
0023         -g <gid>       Group ID to map to group ID 0 (root).
0024                        <gid> is only meaningful if <cpio_source> is a
0025                        directory.  "squash" forces all files to gid 0.
0026         <cpio_source>  File list or directory for cpio archive.
0027                        If <cpio_source> is a .cpio file it will be used
0028                        as direct input to initramfs.
0029 
0030 All options except -o and -l may be repeated and are interpreted
0031 sequentially and immediately.  -u and -g states are preserved across
0032 <cpio_source> options so an explicit "-u 0 -g 0" is required
0033 to reset the root/group mapping.
0034 EOF
0035 }
0036 
0037 # awk style field access
0038 # $1 - field number; rest is argument string
0039 field() {
0040         shift $1 ; echo $1
0041 }
0042 
0043 filetype() {
0044         local argv1="$1"
0045 
0046         # symlink test must come before file test
0047         if [ -L "${argv1}" ]; then
0048                 echo "slink"
0049         elif [ -f "${argv1}" ]; then
0050                 echo "file"
0051         elif [ -d "${argv1}" ]; then
0052                 echo "dir"
0053         elif [ -b "${argv1}" -o -c "${argv1}" ]; then
0054                 echo "nod"
0055         elif [ -p "${argv1}" ]; then
0056                 echo "pipe"
0057         elif [ -S "${argv1}" ]; then
0058                 echo "sock"
0059         else
0060                 echo "invalid"
0061         fi
0062         return 0
0063 }
0064 
0065 print_mtime() {
0066         local my_mtime="0"
0067 
0068         if [ -e "$1" ]; then
0069                 my_mtime=$(find "$1" -printf "%T@\n" | sort -r | head -n 1)
0070         fi
0071 
0072         echo "# Last modified: ${my_mtime}" >> $cpio_list
0073         echo "" >> $cpio_list
0074 }
0075 
0076 list_parse() {
0077         if [ -z "$dep_list" -o -L "$1" ]; then
0078                 return
0079         fi
0080         echo "$1" | sed 's/:/\\:/g; s/$/ \\/' >> $dep_list
0081 }
0082 
0083 # for each file print a line in following format
0084 # <filetype> <name> <path to file> <octal mode> <uid> <gid>
0085 # for links, devices etc the format differs. See gen_init_cpio for details
0086 parse() {
0087         local location="$1"
0088         local name="/${location#${srcdir}}"
0089         # change '//' into '/'
0090         name=$(echo "$name" | sed -e 's://*:/:g')
0091         local mode="$2"
0092         local uid="$3"
0093         local gid="$4"
0094         local ftype=$(filetype "${location}")
0095         # remap uid/gid to 0 if necessary
0096         [ "$root_uid" = "squash" ] && uid=0 || [ "$uid" -eq "$root_uid" ] && uid=0
0097         [ "$root_gid" = "squash" ] && gid=0 || [ "$gid" -eq "$root_gid" ] && gid=0
0098         local str="${mode} ${uid} ${gid}"
0099 
0100         [ "${ftype}" = "invalid" ] && return 0
0101         [ "${location}" = "${srcdir}" ] && return 0
0102 
0103         case "${ftype}" in
0104                 "file")
0105                         str="${ftype} ${name} ${location} ${str}"
0106                         ;;
0107                 "nod")
0108                         local dev="`LC_ALL=C ls -l "${location}"`"
0109                         local maj=`field 5 ${dev}`
0110                         local min=`field 6 ${dev}`
0111                         maj=${maj%,}
0112 
0113                         [ -b "${location}" ] && dev="b" || dev="c"
0114 
0115                         str="${ftype} ${name} ${str} ${dev} ${maj} ${min}"
0116                         ;;
0117                 "slink")
0118                         local target=`readlink "${location}"`
0119                         str="${ftype} ${name} ${target} ${str}"
0120                         ;;
0121                 *)
0122                         str="${ftype} ${name} ${str}"
0123                         ;;
0124         esac
0125 
0126         echo "${str}" >> $cpio_list
0127 
0128         return 0
0129 }
0130 
0131 unknown_option() {
0132         printf "ERROR: unknown option \"$arg\"\n" >&2
0133         printf "If the filename validly begins with '-', " >&2
0134         printf "then it must be prefixed\n" >&2
0135         printf "by './' so that it won't be interpreted as an option." >&2
0136         printf "\n" >&2
0137         usage >&2
0138         exit 1
0139 }
0140 
0141 header() {
0142         printf "\n#####################\n# $1\n" >> $cpio_list
0143 }
0144 
0145 # process one directory (incl sub-directories)
0146 dir_filelist() {
0147         header "$1"
0148 
0149         srcdir=$(echo "$1" | sed -e 's://*:/:g')
0150         dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" | LC_ALL=C sort)
0151 
0152         # If $dirlist is only one line, then the directory is empty
0153         if [  "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then
0154                 print_mtime "$1"
0155 
0156                 echo "${dirlist}" | \
0157                 while read x; do
0158                         list_parse $x
0159                         parse $x
0160                 done
0161         fi
0162 }
0163 
0164 input_file() {
0165         source="$1"
0166         if [ -f "$1" ]; then
0167                 # If a regular file is specified, assume it is in
0168                 # gen_init_cpio format
0169                 header "$1"
0170                 print_mtime "$1" >> $cpio_list
0171                 cat "$1"         >> $cpio_list
0172                 if [ -n "$dep_list" ]; then
0173                         echo "$1 \\"  >> $dep_list
0174                         cat "$1" | while read type dir file perm ; do
0175                                 if [ "$type" = "file" ]; then
0176                                         echo "$file \\" >> $dep_list
0177                                 fi
0178                         done
0179                 fi
0180         elif [ -d "$1" ]; then
0181                 # If a directory is specified then add all files in it to fs
0182                 dir_filelist "$1"
0183         else
0184                 echo "  ${prog}: Cannot open '$1'" >&2
0185                 exit 1
0186         fi
0187 }
0188 
0189 prog=$0
0190 root_uid=0
0191 root_gid=0
0192 dep_list=
0193 cpio_list=$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)
0194 output="/dev/stdout"
0195 
0196 trap "rm -f $cpio_list" EXIT
0197 
0198 while [ $# -gt 0 ]; do
0199         arg="$1"
0200         shift
0201         case "$arg" in
0202                 "-l")   # files included in initramfs - used by kbuild
0203                         dep_list="$1"
0204                         echo "deps_initramfs := \\" > $dep_list
0205                         shift
0206                         ;;
0207                 "-o")   # generate cpio image named $1
0208                         output="$1"
0209                         shift
0210                         ;;
0211                 "-u")   # map $1 to uid=0 (root)
0212                         root_uid="$1"
0213                         [ "$root_uid" = "-1" ] && root_uid=$(id -u || echo 0)
0214                         shift
0215                         ;;
0216                 "-g")   # map $1 to gid=0 (root)
0217                         root_gid="$1"
0218                         [ "$root_gid" = "-1" ] && root_gid=$(id -g || echo 0)
0219                         shift
0220                         ;;
0221                 "-h")
0222                         usage
0223                         exit 0
0224                         ;;
0225                 *)
0226                         case "$arg" in
0227                                 "-"*)
0228                                         unknown_option
0229                                         ;;
0230                                 *)      # input file/dir - process it
0231                                         input_file "$arg"
0232                                         ;;
0233                         esac
0234                         ;;
0235         esac
0236 done
0237 
0238 # If output_file is set we will generate cpio archive
0239 # we are careful to delete tmp files
0240 timestamp=
0241 if test -n "$KBUILD_BUILD_TIMESTAMP"; then
0242         timestamp="$(date -d"$KBUILD_BUILD_TIMESTAMP" +%s || :)"
0243         if test -n "$timestamp"; then
0244                 timestamp="-t $timestamp"
0245         fi
0246 fi
0247 usr/gen_init_cpio $timestamp $cpio_list > $output