linux/usr/gen_initramfs.sh
<<
>>
Prefs
   1#!/bin/sh
   2# Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org>
   3# Copyright (C) 2006 Sam Ravnborg <sam@ravnborg.org>
   4#
   5# Released under the terms of the GNU GPL
   6#
   7# Generate a cpio packed initramfs. It uses gen_init_cpio to generate
   8# the cpio archive.
   9# This script assumes that gen_init_cpio is located in usr/ directory
  10
  11# error out on errors
  12set -e
  13
  14usage() {
  15cat << EOF
  16Usage:
  17$0 [-o <file>] [-l <dep_list>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ...
  18        -o <file>      Create initramfs file named <file> by using gen_init_cpio
  19        -l <dep_list>  Create dependency list named <dep_list>
  20        -u <uid>       User ID to map to user ID 0 (root).
  21                       <uid> is only meaningful if <cpio_source> is a
  22                       directory.  "squash" forces all files to uid 0.
  23        -g <gid>       Group ID to map to group ID 0 (root).
  24                       <gid> is only meaningful if <cpio_source> is a
  25                       directory.  "squash" forces all files to gid 0.
  26        -d <date>      Use date for all file mtime values
  27        <cpio_source>  File list or directory for cpio archive.
  28                       If <cpio_source> is a .cpio file it will be used
  29                       as direct input to initramfs.
  30
  31All options except -o and -l may be repeated and are interpreted
  32sequentially and immediately.  -u and -g states are preserved across
  33<cpio_source> options so an explicit "-u 0 -g 0" is required
  34to reset the root/group mapping.
  35EOF
  36}
  37
  38# awk style field access
  39# $1 - field number; rest is argument string
  40field() {
  41        shift $1 ; echo $1
  42}
  43
  44filetype() {
  45        local argv1="$1"
  46
  47        # symlink test must come before file test
  48        if [ -L "${argv1}" ]; then
  49                echo "slink"
  50        elif [ -f "${argv1}" ]; then
  51                echo "file"
  52        elif [ -d "${argv1}" ]; then
  53                echo "dir"
  54        elif [ -b "${argv1}" -o -c "${argv1}" ]; then
  55                echo "nod"
  56        elif [ -p "${argv1}" ]; then
  57                echo "pipe"
  58        elif [ -S "${argv1}" ]; then
  59                echo "sock"
  60        else
  61                echo "invalid"
  62        fi
  63        return 0
  64}
  65
  66print_mtime() {
  67        local my_mtime="0"
  68
  69        if [ -e "$1" ]; then
  70                my_mtime=$(find "$1" -printf "%T@\n" | sort -r | head -n 1)
  71        fi
  72
  73        echo "# Last modified: ${my_mtime}" >> $cpio_list
  74        echo "" >> $cpio_list
  75}
  76
  77list_parse() {
  78        if [ -z "$dep_list" -o -L "$1" ]; then
  79                return
  80        fi
  81        echo "$1" | sed 's/:/\\:/g; s/$/ \\/' >> $dep_list
  82}
  83
  84# for each file print a line in following format
  85# <filetype> <name> <path to file> <octal mode> <uid> <gid>
  86# for links, devices etc the format differs. See gen_init_cpio for details
  87parse() {
  88        local location="$1"
  89        local name="/${location#${srcdir}}"
  90        # change '//' into '/'
  91        name=$(echo "$name" | sed -e 's://*:/:g')
  92        local mode="$2"
  93        local uid="$3"
  94        local gid="$4"
  95        local ftype=$(filetype "${location}")
  96        # remap uid/gid to 0 if necessary
  97        [ "$root_uid" = "squash" ] && uid=0 || [ "$uid" -eq "$root_uid" ] && uid=0
  98        [ "$root_gid" = "squash" ] && gid=0 || [ "$gid" -eq "$root_gid" ] && gid=0
  99        local str="${mode} ${uid} ${gid}"
 100
 101        [ "${ftype}" = "invalid" ] && return 0
 102        [ "${location}" = "${srcdir}" ] && return 0
 103
 104        case "${ftype}" in
 105                "file")
 106                        str="${ftype} ${name} ${location} ${str}"
 107                        ;;
 108                "nod")
 109                        local dev="`LC_ALL=C ls -l "${location}"`"
 110                        local maj=`field 5 ${dev}`
 111                        local min=`field 6 ${dev}`
 112                        maj=${maj%,}
 113
 114                        [ -b "${location}" ] && dev="b" || dev="c"
 115
 116                        str="${ftype} ${name} ${str} ${dev} ${maj} ${min}"
 117                        ;;
 118                "slink")
 119                        local target=`readlink "${location}"`
 120                        str="${ftype} ${name} ${target} ${str}"
 121                        ;;
 122                *)
 123                        str="${ftype} ${name} ${str}"
 124                        ;;
 125        esac
 126
 127        echo "${str}" >> $cpio_list
 128
 129        return 0
 130}
 131
 132unknown_option() {
 133        printf "ERROR: unknown option \"$arg\"\n" >&2
 134        printf "If the filename validly begins with '-', " >&2
 135        printf "then it must be prefixed\n" >&2
 136        printf "by './' so that it won't be interpreted as an option." >&2
 137        printf "\n" >&2
 138        usage >&2
 139        exit 1
 140}
 141
 142header() {
 143        printf "\n#####################\n# $1\n" >> $cpio_list
 144}
 145
 146# process one directory (incl sub-directories)
 147dir_filelist() {
 148        header "$1"
 149
 150        srcdir=$(echo "$1" | sed -e 's://*:/:g')
 151        dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" | LC_ALL=C sort)
 152
 153        # If $dirlist is only one line, then the directory is empty
 154        if [  "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then
 155                print_mtime "$1"
 156
 157                echo "${dirlist}" | \
 158                while read x; do
 159                        list_parse $x
 160                        parse $x
 161                done
 162        fi
 163}
 164
 165input_file() {
 166        source="$1"
 167        if [ -f "$1" ]; then
 168                # If a regular file is specified, assume it is in
 169                # gen_init_cpio format
 170                header "$1"
 171                print_mtime "$1" >> $cpio_list
 172                cat "$1"         >> $cpio_list
 173                if [ -n "$dep_list" ]; then
 174                        echo "$1 \\"  >> $dep_list
 175                        cat "$1" | while read type dir file perm ; do
 176                                if [ "$type" = "file" ]; then
 177                                        echo "$file \\" >> $dep_list
 178                                fi
 179                        done
 180                fi
 181        elif [ -d "$1" ]; then
 182                # If a directory is specified then add all files in it to fs
 183                dir_filelist "$1"
 184        else
 185                echo "  ${prog}: Cannot open '$1'" >&2
 186                exit 1
 187        fi
 188}
 189
 190prog=$0
 191root_uid=0
 192root_gid=0
 193dep_list=
 194timestamp=
 195cpio_list=$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)
 196output="/dev/stdout"
 197
 198trap "rm -f $cpio_list" EXIT
 199
 200while [ $# -gt 0 ]; do
 201        arg="$1"
 202        shift
 203        case "$arg" in
 204                "-l")   # files included in initramfs - used by kbuild
 205                        dep_list="$1"
 206                        echo "deps_initramfs := \\" > $dep_list
 207                        shift
 208                        ;;
 209                "-o")   # generate cpio image named $1
 210                        output="$1"
 211                        shift
 212                        ;;
 213                "-u")   # map $1 to uid=0 (root)
 214                        root_uid="$1"
 215                        [ "$root_uid" = "-1" ] && root_uid=$(id -u || echo 0)
 216                        shift
 217                        ;;
 218                "-g")   # map $1 to gid=0 (root)
 219                        root_gid="$1"
 220                        [ "$root_gid" = "-1" ] && root_gid=$(id -g || echo 0)
 221                        shift
 222                        ;;
 223                "-d")   # date for file mtimes
 224                        timestamp="$(date -d"$1" +%s || :)"
 225                        if test -n "$timestamp"; then
 226                                timestamp="-t $timestamp"
 227                        fi
 228                        shift
 229                        ;;
 230                "-h")
 231                        usage
 232                        exit 0
 233                        ;;
 234                *)
 235                        case "$arg" in
 236                                "-"*)
 237                                        unknown_option
 238                                        ;;
 239                                *)      # input file/dir - process it
 240                                        input_file "$arg"
 241                                        ;;
 242                        esac
 243                        ;;
 244        esac
 245done
 246
 247# If output_file is set we will generate cpio archive
 248# we are careful to delete tmp files
 249usr/gen_init_cpio $timestamp $cpio_list > $output
 250