2011-05-05 23:03:47 +04:00
#!/bin/sh
2005-04-17 02:20:36 +04:00
# Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org>
2007-02-06 04:18:20 +03:00
# Copyright (C) 2006 Sam Ravnborg <sam@ravnborg.org>
2005-04-17 02:20:36 +04:00
#
2006-04-11 15:24:32 +04:00
# Released under the terms of the GNU GPL
2005-04-17 02:20:36 +04:00
#
2006-04-11 15:24:32 +04:00
# Generate a cpio packed initramfs. It uses gen_init_cpio to generate
2020-01-04 18:02:37 +03:00
# the cpio archive.
2006-04-11 15:24:32 +04:00
# This script assumes that gen_init_cpio is located in usr/ directory
# error out on errors
set -e
usage( ) {
cat << EOF
Usage:
2020-01-04 18:02:34 +03:00
$0 [ -o <file>] [ -l <dep_list>] [ -u <uid>] [ -g <gid>] { -d | <cpio_source>} ...
2020-01-04 18:02:37 +03:00
-o <file> Create initramfs file named <file> by using gen_init_cpio
2020-01-04 18:02:34 +03:00
-l <dep_list> Create dependency list named <dep_list>
2006-04-11 15:24:32 +04:00
-u <uid> User ID to map to user ID 0 ( root) .
2007-05-11 09:44:28 +04:00
<uid> is only meaningful if <cpio_source> is a
directory. "squash" forces all files to uid 0.
2006-04-11 15:24:32 +04:00
-g <gid> Group ID to map to group ID 0 ( root) .
2007-05-11 09:44:28 +04:00
<gid> is only meaningful if <cpio_source> is a
directory. "squash" forces all files to gid 0.
2023-06-06 09:17:41 +03:00
-d <date> Use date for all file mtime values
2006-04-11 15:24:32 +04:00
<cpio_source> File list or directory for cpio archive.
2007-02-06 04:18:20 +03:00
If <cpio_source> is a .cpio file it will be used
2006-04-11 15:24:32 +04:00
as direct input to initramfs.
All options except -o and -l may be repeated and are interpreted
sequentially and immediately. -u and -g states are preserved across
<cpio_source> options so an explicit "-u 0 -g 0" is required
to reset the root/group mapping.
EOF
}
2007-02-06 04:18:20 +03:00
# awk style field access
# $1 - field number; rest is argument string
field( ) {
shift $1 ; echo $1
}
2005-04-17 02:20:36 +04:00
filetype( ) {
local argv1 = " $1 "
# symlink test must come before file test
if [ -L " ${ argv1 } " ] ; then
echo "slink"
elif [ -f " ${ argv1 } " ] ; then
echo "file"
elif [ -d " ${ argv1 } " ] ; then
echo "dir"
elif [ -b " ${ argv1 } " -o -c " ${ argv1 } " ] ; then
echo "nod"
elif [ -p " ${ argv1 } " ] ; then
echo "pipe"
elif [ -S " ${ argv1 } " ] ; then
echo "sock"
else
echo "invalid"
fi
return 0
}
print_mtime( ) {
local my_mtime = "0"
2006-04-11 15:24:32 +04:00
if [ -e " $1 " ] ; then
my_mtime = $( find " $1 " -printf "%T@\n" | sort -r | head -n 1)
2005-04-17 02:20:36 +04:00
fi
2006-04-11 15:24:32 +04:00
2020-01-04 18:02:36 +03:00
echo " # Last modified: ${ my_mtime } " >> $cpio_list
echo "" >> $cpio_list
2006-04-11 15:24:32 +04:00
}
list_parse( ) {
2020-01-04 18:02:34 +03:00
if [ -z " $dep_list " -o -L " $1 " ] ; then
2016-09-23 10:56:05 +03:00
return
fi
2020-01-04 18:02:34 +03:00
echo " $1 " | sed 's/:/\\:/g; s/$/ \\/' >> $dep_list
2005-04-17 02:20:36 +04:00
}
2006-04-11 15:24:32 +04:00
# for each file print a line in following format
# <filetype> <name> <path to file> <octal mode> <uid> <gid>
# for links, devices etc the format differs. See gen_init_cpio for details
2005-04-17 02:20:36 +04:00
parse( ) {
local location = " $1 "
2011-05-05 23:03:47 +04:00
local name = " / ${ location # ${ srcdir } } "
2005-04-17 02:20:36 +04:00
# change '//' into '/'
2011-05-05 23:03:47 +04:00
name = $( echo " $name " | sed -e 's://*:/:g' )
2005-04-17 02:20:36 +04:00
local mode = " $2 "
local uid = " $3 "
local gid = " $4 "
local ftype = $( filetype " ${ location } " )
# remap uid/gid to 0 if necessary
2007-05-11 09:44:28 +04:00
[ " $root_uid " = "squash" ] && uid = 0 || [ " $uid " -eq " $root_uid " ] && uid = 0
[ " $root_gid " = "squash" ] && gid = 0 || [ " $gid " -eq " $root_gid " ] && gid = 0
2005-04-17 02:20:36 +04:00
local str = " ${ mode } ${ uid } ${ gid } "
2011-05-05 23:03:47 +04:00
[ " ${ ftype } " = "invalid" ] && return 0
[ " ${ location } " = " ${ srcdir } " ] && return 0
2005-04-17 02:20:36 +04:00
case " ${ ftype } " in
"file" )
str = " ${ ftype } ${ name } ${ location } ${ str } "
; ;
"nod" )
2019-12-30 16:20:06 +03:00
local dev = "`LC_ALL=C ls -l " ${ location } "`"
2007-02-06 04:18:20 +03:00
local maj = ` field 5 ${ dev } `
local min = ` field 6 ${ dev } `
maj = ${ maj %, }
[ -b " ${ location } " ] && dev = "b" || dev = "c"
str = " ${ ftype } ${ name } ${ str } ${ dev } ${ maj } ${ min } "
2005-04-17 02:20:36 +04:00
; ;
"slink" )
2008-04-02 16:50:05 +04:00
local target = ` readlink " ${ location } " `
2005-04-17 02:20:36 +04:00
str = " ${ ftype } ${ name } ${ target } ${ str } "
; ;
*)
str = " ${ ftype } ${ name } ${ str } "
; ;
esac
2020-01-04 18:02:36 +03:00
echo " ${ str } " >> $cpio_list
2005-04-17 02:20:36 +04:00
return 0
}
2006-04-11 15:24:32 +04:00
unknown_option( ) {
printf " ERROR: unknown option \" $arg \"\n " >& 2
printf "If the filename validly begins with '-', " >& 2
printf "then it must be prefixed\n" >& 2
printf "by './' so that it won't be interpreted as an option." >& 2
printf "\n" >& 2
usage >& 2
exit 1
}
header( ) {
2020-01-04 18:02:36 +03:00
printf " \n#####################\n# $1 \n " >> $cpio_list
2006-04-11 15:24:32 +04:00
}
# process one directory (incl sub-directories)
dir_filelist( ) {
2020-01-04 18:02:34 +03:00
header " $1 "
2006-04-11 15:24:32 +04:00
srcdir = $( echo " $1 " | sed -e 's://*:/:g' )
2021-04-30 04:56:27 +03:00
dirlist = $( find " ${ srcdir } " -printf "%p %m %U %G\n" | LC_ALL = C sort)
2006-04-11 15:24:32 +04:00
# If $dirlist is only one line, then the directory is empty
if [ " $( echo " ${ dirlist } " | wc -l) " -gt 1 ] ; then
2020-01-04 18:02:34 +03:00
print_mtime " $1 "
2006-04-11 15:24:32 +04:00
echo " ${ dirlist } " | \
while read x; do
2020-01-04 18:02:34 +03:00
list_parse $x
parse $x
2006-04-11 15:24:32 +04:00
done
fi
2005-04-17 02:20:36 +04:00
}
2006-04-11 15:24:32 +04:00
input_file( ) {
source = " $1 "
if [ -f " $1 " ] ; then
2020-01-04 18:02:37 +03:00
# If a regular file is specified, assume it is in
# gen_init_cpio format
2020-01-04 18:02:34 +03:00
header " $1 "
2020-01-04 18:02:36 +03:00
print_mtime " $1 " >> $cpio_list
cat " $1 " >> $cpio_list
2020-01-04 18:02:34 +03:00
if [ -n " $dep_list " ] ; then
echo " $1 \\ " >> $dep_list
2006-05-01 01:56:33 +04:00
cat " $1 " | while read type dir file perm ; do
2011-05-05 23:03:47 +04:00
if [ " $type " = "file" ] ; then
2020-01-04 18:02:34 +03:00
echo " $file \\ " >> $dep_list
2006-05-01 01:56:33 +04:00
fi
done
2005-04-17 02:20:36 +04:00
fi
2006-04-11 15:24:32 +04:00
elif [ -d " $1 " ] ; then
2020-01-04 18:02:37 +03:00
# If a directory is specified then add all files in it to fs
2006-04-11 15:24:32 +04:00
dir_filelist " $1 "
2005-04-17 02:20:36 +04:00
else
2006-04-11 15:24:32 +04:00
echo " ${ prog } : Cannot open ' $1 ' " >& 2
2005-04-17 02:20:36 +04:00
exit 1
fi
}
2006-04-11 15:24:32 +04:00
prog = $0
2005-04-17 02:20:36 +04:00
root_uid = 0
root_gid = 0
2006-04-11 15:24:32 +04:00
dep_list =
2023-06-06 09:17:41 +03:00
timestamp =
2020-01-04 18:02:36 +03:00
cpio_list = $( mktemp ${ TMPDIR :- /tmp } /cpiolist.XXXXXX)
2006-04-11 15:24:32 +04:00
output = "/dev/stdout"
2005-04-17 02:20:36 +04:00
2020-01-04 18:02:38 +03:00
trap " rm -f $cpio_list " EXIT
2005-04-17 02:20:36 +04:00
while [ $# -gt 0 ] ; do
arg = " $1 "
shift
case " $arg " in
2020-01-04 18:02:34 +03:00
"-l" ) # files included in initramfs - used by kbuild
dep_list = " $1 "
echo "deps_initramfs := \\" > $dep_list
shift
; ;
2020-01-04 18:02:37 +03:00
"-o" ) # generate cpio image named $1
output = " $1 "
2020-01-04 18:02:34 +03:00
shift
; ;
2006-04-11 15:24:32 +04:00
"-u" ) # map $1 to uid=0 (root)
2005-04-17 02:20:36 +04:00
root_uid = " $1 "
2017-07-07 01:35:43 +03:00
[ " $root_uid " = "-1" ] && root_uid = $( id -u || echo 0)
2005-04-17 02:20:36 +04:00
shift
; ;
2006-04-11 15:24:32 +04:00
"-g" ) # map $1 to gid=0 (root)
2005-04-17 02:20:36 +04:00
root_gid = " $1 "
2017-07-07 01:35:43 +03:00
[ " $root_gid " = "-1" ] && root_gid = $( id -g || echo 0)
2005-04-17 02:20:36 +04:00
shift
; ;
2023-06-06 09:17:41 +03:00
"-d" ) # date for file mtimes
timestamp = " $( date -d" $1 " +%s || :) "
if test -n " $timestamp " ; then
timestamp = " -t $timestamp "
fi
shift
; ;
2005-04-17 02:20:36 +04:00
"-h" )
usage
exit 0
; ;
*)
case " $arg " in
"-" *)
2006-04-11 15:24:32 +04:00
unknown_option
2005-04-17 02:20:36 +04:00
; ;
2006-04-11 15:24:32 +04:00
*) # input file/dir - process it
2020-01-04 18:02:37 +03:00
input_file " $arg "
2005-04-17 02:20:36 +04:00
; ;
esac
; ;
esac
done
2020-01-04 18:02:37 +03:00
# If output_file is set we will generate cpio archive
2011-03-31 05:57:33 +04:00
# we are careful to delete tmp files
2020-01-04 18:02:37 +03:00
usr/gen_init_cpio $timestamp $cpio_list > $output