180e715a0SMasahiro Yamada#!/bin/sh 280e715a0SMasahiro Yamada# Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org> 380e715a0SMasahiro Yamada# Copyright (C) 2006 Sam Ravnborg <sam@ravnborg.org> 480e715a0SMasahiro Yamada# 580e715a0SMasahiro Yamada# Released under the terms of the GNU GPL 680e715a0SMasahiro Yamada# 780e715a0SMasahiro Yamada# Generate a cpio packed initramfs. It uses gen_init_cpio to generate 865e00e04SMasahiro Yamada# the cpio archive. 980e715a0SMasahiro Yamada# This script assumes that gen_init_cpio is located in usr/ directory 1080e715a0SMasahiro Yamada 1180e715a0SMasahiro Yamada# error out on errors 1280e715a0SMasahiro Yamadaset -e 1380e715a0SMasahiro Yamada 1480e715a0SMasahiro Yamadausage() { 1580e715a0SMasahiro Yamadacat << EOF 1680e715a0SMasahiro YamadaUsage: 1796680975SMasahiro Yamada$0 [-o <file>] [-l <dep_list>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ... 1865e00e04SMasahiro Yamada -o <file> Create initramfs file named <file> by using gen_init_cpio 1996680975SMasahiro Yamada -l <dep_list> Create dependency list named <dep_list> 2080e715a0SMasahiro Yamada -u <uid> User ID to map to user ID 0 (root). 2180e715a0SMasahiro Yamada <uid> is only meaningful if <cpio_source> is a 2280e715a0SMasahiro Yamada directory. "squash" forces all files to uid 0. 2380e715a0SMasahiro Yamada -g <gid> Group ID to map to group ID 0 (root). 2480e715a0SMasahiro Yamada <gid> is only meaningful if <cpio_source> is a 2580e715a0SMasahiro Yamada directory. "squash" forces all files to gid 0. 26*7f8256aeSBenjamin Gray -d <date> Use date for all file mtime values 2780e715a0SMasahiro Yamada <cpio_source> File list or directory for cpio archive. 2880e715a0SMasahiro Yamada If <cpio_source> is a .cpio file it will be used 2980e715a0SMasahiro Yamada as direct input to initramfs. 3080e715a0SMasahiro Yamada 3180e715a0SMasahiro YamadaAll options except -o and -l may be repeated and are interpreted 3280e715a0SMasahiro Yamadasequentially and immediately. -u and -g states are preserved across 3380e715a0SMasahiro Yamada<cpio_source> options so an explicit "-u 0 -g 0" is required 3480e715a0SMasahiro Yamadato reset the root/group mapping. 3580e715a0SMasahiro YamadaEOF 3680e715a0SMasahiro Yamada} 3780e715a0SMasahiro Yamada 3880e715a0SMasahiro Yamada# awk style field access 3980e715a0SMasahiro Yamada# $1 - field number; rest is argument string 4080e715a0SMasahiro Yamadafield() { 4180e715a0SMasahiro Yamada shift $1 ; echo $1 4280e715a0SMasahiro Yamada} 4380e715a0SMasahiro Yamada 4480e715a0SMasahiro Yamadafiletype() { 4580e715a0SMasahiro Yamada local argv1="$1" 4680e715a0SMasahiro Yamada 4780e715a0SMasahiro Yamada # symlink test must come before file test 4880e715a0SMasahiro Yamada if [ -L "${argv1}" ]; then 4980e715a0SMasahiro Yamada echo "slink" 5080e715a0SMasahiro Yamada elif [ -f "${argv1}" ]; then 5180e715a0SMasahiro Yamada echo "file" 5280e715a0SMasahiro Yamada elif [ -d "${argv1}" ]; then 5380e715a0SMasahiro Yamada echo "dir" 5480e715a0SMasahiro Yamada elif [ -b "${argv1}" -o -c "${argv1}" ]; then 5580e715a0SMasahiro Yamada echo "nod" 5680e715a0SMasahiro Yamada elif [ -p "${argv1}" ]; then 5780e715a0SMasahiro Yamada echo "pipe" 5880e715a0SMasahiro Yamada elif [ -S "${argv1}" ]; then 5980e715a0SMasahiro Yamada echo "sock" 6080e715a0SMasahiro Yamada else 6180e715a0SMasahiro Yamada echo "invalid" 6280e715a0SMasahiro Yamada fi 6380e715a0SMasahiro Yamada return 0 6480e715a0SMasahiro Yamada} 6580e715a0SMasahiro Yamada 6680e715a0SMasahiro Yamadaprint_mtime() { 6780e715a0SMasahiro Yamada local my_mtime="0" 6880e715a0SMasahiro Yamada 6980e715a0SMasahiro Yamada if [ -e "$1" ]; then 7080e715a0SMasahiro Yamada my_mtime=$(find "$1" -printf "%T@\n" | sort -r | head -n 1) 7180e715a0SMasahiro Yamada fi 7280e715a0SMasahiro Yamada 73469e87e8SMasahiro Yamada echo "# Last modified: ${my_mtime}" >> $cpio_list 74469e87e8SMasahiro Yamada echo "" >> $cpio_list 7580e715a0SMasahiro Yamada} 7680e715a0SMasahiro Yamada 7780e715a0SMasahiro Yamadalist_parse() { 7896680975SMasahiro Yamada if [ -z "$dep_list" -o -L "$1" ]; then 7980e715a0SMasahiro Yamada return 8080e715a0SMasahiro Yamada fi 8196680975SMasahiro Yamada echo "$1" | sed 's/:/\\:/g; s/$/ \\/' >> $dep_list 8280e715a0SMasahiro Yamada} 8380e715a0SMasahiro Yamada 8480e715a0SMasahiro Yamada# for each file print a line in following format 8580e715a0SMasahiro Yamada# <filetype> <name> <path to file> <octal mode> <uid> <gid> 8680e715a0SMasahiro Yamada# for links, devices etc the format differs. See gen_init_cpio for details 8780e715a0SMasahiro Yamadaparse() { 8880e715a0SMasahiro Yamada local location="$1" 8980e715a0SMasahiro Yamada local name="/${location#${srcdir}}" 9080e715a0SMasahiro Yamada # change '//' into '/' 9180e715a0SMasahiro Yamada name=$(echo "$name" | sed -e 's://*:/:g') 9280e715a0SMasahiro Yamada local mode="$2" 9380e715a0SMasahiro Yamada local uid="$3" 9480e715a0SMasahiro Yamada local gid="$4" 9580e715a0SMasahiro Yamada local ftype=$(filetype "${location}") 9680e715a0SMasahiro Yamada # remap uid/gid to 0 if necessary 9780e715a0SMasahiro Yamada [ "$root_uid" = "squash" ] && uid=0 || [ "$uid" -eq "$root_uid" ] && uid=0 9880e715a0SMasahiro Yamada [ "$root_gid" = "squash" ] && gid=0 || [ "$gid" -eq "$root_gid" ] && gid=0 9980e715a0SMasahiro Yamada local str="${mode} ${uid} ${gid}" 10080e715a0SMasahiro Yamada 10180e715a0SMasahiro Yamada [ "${ftype}" = "invalid" ] && return 0 10280e715a0SMasahiro Yamada [ "${location}" = "${srcdir}" ] && return 0 10380e715a0SMasahiro Yamada 10480e715a0SMasahiro Yamada case "${ftype}" in 10580e715a0SMasahiro Yamada "file") 10680e715a0SMasahiro Yamada str="${ftype} ${name} ${location} ${str}" 10780e715a0SMasahiro Yamada ;; 10880e715a0SMasahiro Yamada "nod") 10980e715a0SMasahiro Yamada local dev="`LC_ALL=C ls -l "${location}"`" 11080e715a0SMasahiro Yamada local maj=`field 5 ${dev}` 11180e715a0SMasahiro Yamada local min=`field 6 ${dev}` 11280e715a0SMasahiro Yamada maj=${maj%,} 11380e715a0SMasahiro Yamada 11480e715a0SMasahiro Yamada [ -b "${location}" ] && dev="b" || dev="c" 11580e715a0SMasahiro Yamada 11680e715a0SMasahiro Yamada str="${ftype} ${name} ${str} ${dev} ${maj} ${min}" 11780e715a0SMasahiro Yamada ;; 11880e715a0SMasahiro Yamada "slink") 11980e715a0SMasahiro Yamada local target=`readlink "${location}"` 12080e715a0SMasahiro Yamada str="${ftype} ${name} ${target} ${str}" 12180e715a0SMasahiro Yamada ;; 12280e715a0SMasahiro Yamada *) 12380e715a0SMasahiro Yamada str="${ftype} ${name} ${str}" 12480e715a0SMasahiro Yamada ;; 12580e715a0SMasahiro Yamada esac 12680e715a0SMasahiro Yamada 127469e87e8SMasahiro Yamada echo "${str}" >> $cpio_list 12880e715a0SMasahiro Yamada 12980e715a0SMasahiro Yamada return 0 13080e715a0SMasahiro Yamada} 13180e715a0SMasahiro Yamada 13280e715a0SMasahiro Yamadaunknown_option() { 13380e715a0SMasahiro Yamada printf "ERROR: unknown option \"$arg\"\n" >&2 13480e715a0SMasahiro Yamada printf "If the filename validly begins with '-', " >&2 13580e715a0SMasahiro Yamada printf "then it must be prefixed\n" >&2 13680e715a0SMasahiro Yamada printf "by './' so that it won't be interpreted as an option." >&2 13780e715a0SMasahiro Yamada printf "\n" >&2 13880e715a0SMasahiro Yamada usage >&2 13980e715a0SMasahiro Yamada exit 1 14080e715a0SMasahiro Yamada} 14180e715a0SMasahiro Yamada 14280e715a0SMasahiro Yamadaheader() { 143469e87e8SMasahiro Yamada printf "\n#####################\n# $1\n" >> $cpio_list 14480e715a0SMasahiro Yamada} 14580e715a0SMasahiro Yamada 14680e715a0SMasahiro Yamada# process one directory (incl sub-directories) 14780e715a0SMasahiro Yamadadir_filelist() { 14896680975SMasahiro Yamada header "$1" 14980e715a0SMasahiro Yamada 15080e715a0SMasahiro Yamada srcdir=$(echo "$1" | sed -e 's://*:/:g') 15177a88274SMasahiro Yamada dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" | LC_ALL=C sort) 15280e715a0SMasahiro Yamada 15380e715a0SMasahiro Yamada # If $dirlist is only one line, then the directory is empty 15480e715a0SMasahiro Yamada if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then 15596680975SMasahiro Yamada print_mtime "$1" 15680e715a0SMasahiro Yamada 15780e715a0SMasahiro Yamada echo "${dirlist}" | \ 15880e715a0SMasahiro Yamada while read x; do 15996680975SMasahiro Yamada list_parse $x 16096680975SMasahiro Yamada parse $x 16180e715a0SMasahiro Yamada done 16280e715a0SMasahiro Yamada fi 16380e715a0SMasahiro Yamada} 16480e715a0SMasahiro Yamada 16580e715a0SMasahiro Yamadainput_file() { 16680e715a0SMasahiro Yamada source="$1" 16780e715a0SMasahiro Yamada if [ -f "$1" ]; then 16865e00e04SMasahiro Yamada # If a regular file is specified, assume it is in 16965e00e04SMasahiro Yamada # gen_init_cpio format 17096680975SMasahiro Yamada header "$1" 171469e87e8SMasahiro Yamada print_mtime "$1" >> $cpio_list 172469e87e8SMasahiro Yamada cat "$1" >> $cpio_list 17396680975SMasahiro Yamada if [ -n "$dep_list" ]; then 17496680975SMasahiro Yamada echo "$1 \\" >> $dep_list 17580e715a0SMasahiro Yamada cat "$1" | while read type dir file perm ; do 17680e715a0SMasahiro Yamada if [ "$type" = "file" ]; then 17796680975SMasahiro Yamada echo "$file \\" >> $dep_list 17880e715a0SMasahiro Yamada fi 17980e715a0SMasahiro Yamada done 18080e715a0SMasahiro Yamada fi 18180e715a0SMasahiro Yamada elif [ -d "$1" ]; then 18265e00e04SMasahiro Yamada # If a directory is specified then add all files in it to fs 18380e715a0SMasahiro Yamada dir_filelist "$1" 18480e715a0SMasahiro Yamada else 18580e715a0SMasahiro Yamada echo " ${prog}: Cannot open '$1'" >&2 18680e715a0SMasahiro Yamada exit 1 18780e715a0SMasahiro Yamada fi 18880e715a0SMasahiro Yamada} 18980e715a0SMasahiro Yamada 19080e715a0SMasahiro Yamadaprog=$0 19180e715a0SMasahiro Yamadaroot_uid=0 19280e715a0SMasahiro Yamadaroot_gid=0 19380e715a0SMasahiro Yamadadep_list= 194*7f8256aeSBenjamin Graytimestamp= 195469e87e8SMasahiro Yamadacpio_list=$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX) 19680e715a0SMasahiro Yamadaoutput="/dev/stdout" 19780e715a0SMasahiro Yamada 1987168965eSMasahiro Yamadatrap "rm -f $cpio_list" EXIT 1997168965eSMasahiro Yamada 20096680975SMasahiro Yamadawhile [ $# -gt 0 ]; do 20180e715a0SMasahiro Yamada arg="$1" 20296680975SMasahiro Yamada shift 20380e715a0SMasahiro Yamada case "$arg" in 20480e715a0SMasahiro Yamada "-l") # files included in initramfs - used by kbuild 20596680975SMasahiro Yamada dep_list="$1" 20696680975SMasahiro Yamada echo "deps_initramfs := \\" > $dep_list 20780e715a0SMasahiro Yamada shift 20880e715a0SMasahiro Yamada ;; 20965e00e04SMasahiro Yamada "-o") # generate cpio image named $1 21065e00e04SMasahiro Yamada output="$1" 21180e715a0SMasahiro Yamada shift 21280e715a0SMasahiro Yamada ;; 21380e715a0SMasahiro Yamada "-u") # map $1 to uid=0 (root) 21480e715a0SMasahiro Yamada root_uid="$1" 21580e715a0SMasahiro Yamada [ "$root_uid" = "-1" ] && root_uid=$(id -u || echo 0) 21680e715a0SMasahiro Yamada shift 21780e715a0SMasahiro Yamada ;; 21880e715a0SMasahiro Yamada "-g") # map $1 to gid=0 (root) 21980e715a0SMasahiro Yamada root_gid="$1" 22080e715a0SMasahiro Yamada [ "$root_gid" = "-1" ] && root_gid=$(id -g || echo 0) 22180e715a0SMasahiro Yamada shift 22280e715a0SMasahiro Yamada ;; 223*7f8256aeSBenjamin Gray "-d") # date for file mtimes 224*7f8256aeSBenjamin Gray timestamp="$(date -d"$1" +%s || :)" 225*7f8256aeSBenjamin Gray if test -n "$timestamp"; then 226*7f8256aeSBenjamin Gray timestamp="-t $timestamp" 227*7f8256aeSBenjamin Gray fi 228*7f8256aeSBenjamin Gray shift 229*7f8256aeSBenjamin Gray ;; 23080e715a0SMasahiro Yamada "-h") 23180e715a0SMasahiro Yamada usage 23280e715a0SMasahiro Yamada exit 0 23380e715a0SMasahiro Yamada ;; 23480e715a0SMasahiro Yamada *) 23580e715a0SMasahiro Yamada case "$arg" in 23680e715a0SMasahiro Yamada "-"*) 23780e715a0SMasahiro Yamada unknown_option 23880e715a0SMasahiro Yamada ;; 23980e715a0SMasahiro Yamada *) # input file/dir - process it 24065e00e04SMasahiro Yamada input_file "$arg" 24180e715a0SMasahiro Yamada ;; 24280e715a0SMasahiro Yamada esac 24380e715a0SMasahiro Yamada ;; 24480e715a0SMasahiro Yamada esac 24580e715a0SMasahiro Yamadadone 24680e715a0SMasahiro Yamada 24765e00e04SMasahiro Yamada# If output_file is set we will generate cpio archive 24880e715a0SMasahiro Yamada# we are careful to delete tmp files 24965e00e04SMasahiro Yamadausr/gen_init_cpio $timestamp $cpio_list > $output 250