18c2ecf20Sopenharmony_ci#!/bin/sh 28c2ecf20Sopenharmony_ci# Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org> 38c2ecf20Sopenharmony_ci# Copyright (C) 2006 Sam Ravnborg <sam@ravnborg.org> 48c2ecf20Sopenharmony_ci# 58c2ecf20Sopenharmony_ci# Released under the terms of the GNU GPL 68c2ecf20Sopenharmony_ci# 78c2ecf20Sopenharmony_ci# Generate a cpio packed initramfs. It uses gen_init_cpio to generate 88c2ecf20Sopenharmony_ci# the cpio archive. 98c2ecf20Sopenharmony_ci# This script assumes that gen_init_cpio is located in usr/ directory 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci# error out on errors 128c2ecf20Sopenharmony_ciset -e 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ciusage() { 158c2ecf20Sopenharmony_cicat << EOF 168c2ecf20Sopenharmony_ciUsage: 178c2ecf20Sopenharmony_ci$0 [-o <file>] [-l <dep_list>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ... 188c2ecf20Sopenharmony_ci -o <file> Create initramfs file named <file> by using gen_init_cpio 198c2ecf20Sopenharmony_ci -l <dep_list> Create dependency list named <dep_list> 208c2ecf20Sopenharmony_ci -u <uid> User ID to map to user ID 0 (root). 218c2ecf20Sopenharmony_ci <uid> is only meaningful if <cpio_source> is a 228c2ecf20Sopenharmony_ci directory. "squash" forces all files to uid 0. 238c2ecf20Sopenharmony_ci -g <gid> Group ID to map to group ID 0 (root). 248c2ecf20Sopenharmony_ci <gid> is only meaningful if <cpio_source> is a 258c2ecf20Sopenharmony_ci directory. "squash" forces all files to gid 0. 268c2ecf20Sopenharmony_ci <cpio_source> File list or directory for cpio archive. 278c2ecf20Sopenharmony_ci If <cpio_source> is a .cpio file it will be used 288c2ecf20Sopenharmony_ci as direct input to initramfs. 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ciAll options except -o and -l may be repeated and are interpreted 318c2ecf20Sopenharmony_cisequentially and immediately. -u and -g states are preserved across 328c2ecf20Sopenharmony_ci<cpio_source> options so an explicit "-u 0 -g 0" is required 338c2ecf20Sopenharmony_cito reset the root/group mapping. 348c2ecf20Sopenharmony_ciEOF 358c2ecf20Sopenharmony_ci} 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci# awk style field access 388c2ecf20Sopenharmony_ci# $1 - field number; rest is argument string 398c2ecf20Sopenharmony_cifield() { 408c2ecf20Sopenharmony_ci shift $1 ; echo $1 418c2ecf20Sopenharmony_ci} 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cifiletype() { 448c2ecf20Sopenharmony_ci local argv1="$1" 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci # symlink test must come before file test 478c2ecf20Sopenharmony_ci if [ -L "${argv1}" ]; then 488c2ecf20Sopenharmony_ci echo "slink" 498c2ecf20Sopenharmony_ci elif [ -f "${argv1}" ]; then 508c2ecf20Sopenharmony_ci echo "file" 518c2ecf20Sopenharmony_ci elif [ -d "${argv1}" ]; then 528c2ecf20Sopenharmony_ci echo "dir" 538c2ecf20Sopenharmony_ci elif [ -b "${argv1}" -o -c "${argv1}" ]; then 548c2ecf20Sopenharmony_ci echo "nod" 558c2ecf20Sopenharmony_ci elif [ -p "${argv1}" ]; then 568c2ecf20Sopenharmony_ci echo "pipe" 578c2ecf20Sopenharmony_ci elif [ -S "${argv1}" ]; then 588c2ecf20Sopenharmony_ci echo "sock" 598c2ecf20Sopenharmony_ci else 608c2ecf20Sopenharmony_ci echo "invalid" 618c2ecf20Sopenharmony_ci fi 628c2ecf20Sopenharmony_ci return 0 638c2ecf20Sopenharmony_ci} 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ciprint_mtime() { 668c2ecf20Sopenharmony_ci local my_mtime="0" 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci if [ -e "$1" ]; then 698c2ecf20Sopenharmony_ci my_mtime=$(find "$1" -printf "%T@\n" | sort -r | head -n 1) 708c2ecf20Sopenharmony_ci fi 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci echo "# Last modified: ${my_mtime}" >> $cpio_list 738c2ecf20Sopenharmony_ci echo "" >> $cpio_list 748c2ecf20Sopenharmony_ci} 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cilist_parse() { 778c2ecf20Sopenharmony_ci if [ -z "$dep_list" -o -L "$1" ]; then 788c2ecf20Sopenharmony_ci return 798c2ecf20Sopenharmony_ci fi 808c2ecf20Sopenharmony_ci echo "$1" | sed 's/:/\\:/g; s/$/ \\/' >> $dep_list 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci# for each file print a line in following format 848c2ecf20Sopenharmony_ci# <filetype> <name> <path to file> <octal mode> <uid> <gid> 858c2ecf20Sopenharmony_ci# for links, devices etc the format differs. See gen_init_cpio for details 868c2ecf20Sopenharmony_ciparse() { 878c2ecf20Sopenharmony_ci local location="$1" 888c2ecf20Sopenharmony_ci local name="/${location#${srcdir}}" 898c2ecf20Sopenharmony_ci # change '//' into '/' 908c2ecf20Sopenharmony_ci name=$(echo "$name" | sed -e 's://*:/:g') 918c2ecf20Sopenharmony_ci local mode="$2" 928c2ecf20Sopenharmony_ci local uid="$3" 938c2ecf20Sopenharmony_ci local gid="$4" 948c2ecf20Sopenharmony_ci local ftype=$(filetype "${location}") 958c2ecf20Sopenharmony_ci # remap uid/gid to 0 if necessary 968c2ecf20Sopenharmony_ci [ "$root_uid" = "squash" ] && uid=0 || [ "$uid" -eq "$root_uid" ] && uid=0 978c2ecf20Sopenharmony_ci [ "$root_gid" = "squash" ] && gid=0 || [ "$gid" -eq "$root_gid" ] && gid=0 988c2ecf20Sopenharmony_ci local str="${mode} ${uid} ${gid}" 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci [ "${ftype}" = "invalid" ] && return 0 1018c2ecf20Sopenharmony_ci [ "${location}" = "${srcdir}" ] && return 0 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci case "${ftype}" in 1048c2ecf20Sopenharmony_ci "file") 1058c2ecf20Sopenharmony_ci str="${ftype} ${name} ${location} ${str}" 1068c2ecf20Sopenharmony_ci ;; 1078c2ecf20Sopenharmony_ci "nod") 1088c2ecf20Sopenharmony_ci local dev="`LC_ALL=C ls -l "${location}"`" 1098c2ecf20Sopenharmony_ci local maj=`field 5 ${dev}` 1108c2ecf20Sopenharmony_ci local min=`field 6 ${dev}` 1118c2ecf20Sopenharmony_ci maj=${maj%,} 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci [ -b "${location}" ] && dev="b" || dev="c" 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci str="${ftype} ${name} ${str} ${dev} ${maj} ${min}" 1168c2ecf20Sopenharmony_ci ;; 1178c2ecf20Sopenharmony_ci "slink") 1188c2ecf20Sopenharmony_ci local target=`readlink "${location}"` 1198c2ecf20Sopenharmony_ci str="${ftype} ${name} ${target} ${str}" 1208c2ecf20Sopenharmony_ci ;; 1218c2ecf20Sopenharmony_ci *) 1228c2ecf20Sopenharmony_ci str="${ftype} ${name} ${str}" 1238c2ecf20Sopenharmony_ci ;; 1248c2ecf20Sopenharmony_ci esac 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci echo "${str}" >> $cpio_list 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci return 0 1298c2ecf20Sopenharmony_ci} 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ciunknown_option() { 1328c2ecf20Sopenharmony_ci printf "ERROR: unknown option \"$arg\"\n" >&2 1338c2ecf20Sopenharmony_ci printf "If the filename validly begins with '-', " >&2 1348c2ecf20Sopenharmony_ci printf "then it must be prefixed\n" >&2 1358c2ecf20Sopenharmony_ci printf "by './' so that it won't be interpreted as an option." >&2 1368c2ecf20Sopenharmony_ci printf "\n" >&2 1378c2ecf20Sopenharmony_ci usage >&2 1388c2ecf20Sopenharmony_ci exit 1 1398c2ecf20Sopenharmony_ci} 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ciheader() { 1428c2ecf20Sopenharmony_ci printf "\n#####################\n# $1\n" >> $cpio_list 1438c2ecf20Sopenharmony_ci} 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci# process one directory (incl sub-directories) 1468c2ecf20Sopenharmony_cidir_filelist() { 1478c2ecf20Sopenharmony_ci header "$1" 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci srcdir=$(echo "$1" | sed -e 's://*:/:g') 1508c2ecf20Sopenharmony_ci dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" | LANG=C sort) 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci # If $dirlist is only one line, then the directory is empty 1538c2ecf20Sopenharmony_ci if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then 1548c2ecf20Sopenharmony_ci print_mtime "$1" 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci echo "${dirlist}" | \ 1578c2ecf20Sopenharmony_ci while read x; do 1588c2ecf20Sopenharmony_ci list_parse $x 1598c2ecf20Sopenharmony_ci parse $x 1608c2ecf20Sopenharmony_ci done 1618c2ecf20Sopenharmony_ci fi 1628c2ecf20Sopenharmony_ci} 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ciinput_file() { 1658c2ecf20Sopenharmony_ci source="$1" 1668c2ecf20Sopenharmony_ci if [ -f "$1" ]; then 1678c2ecf20Sopenharmony_ci # If a regular file is specified, assume it is in 1688c2ecf20Sopenharmony_ci # gen_init_cpio format 1698c2ecf20Sopenharmony_ci header "$1" 1708c2ecf20Sopenharmony_ci print_mtime "$1" >> $cpio_list 1718c2ecf20Sopenharmony_ci cat "$1" >> $cpio_list 1728c2ecf20Sopenharmony_ci if [ -n "$dep_list" ]; then 1738c2ecf20Sopenharmony_ci echo "$1 \\" >> $dep_list 1748c2ecf20Sopenharmony_ci cat "$1" | while read type dir file perm ; do 1758c2ecf20Sopenharmony_ci if [ "$type" = "file" ]; then 1768c2ecf20Sopenharmony_ci echo "$file \\" >> $dep_list 1778c2ecf20Sopenharmony_ci fi 1788c2ecf20Sopenharmony_ci done 1798c2ecf20Sopenharmony_ci fi 1808c2ecf20Sopenharmony_ci elif [ -d "$1" ]; then 1818c2ecf20Sopenharmony_ci # If a directory is specified then add all files in it to fs 1828c2ecf20Sopenharmony_ci dir_filelist "$1" 1838c2ecf20Sopenharmony_ci else 1848c2ecf20Sopenharmony_ci echo " ${prog}: Cannot open '$1'" >&2 1858c2ecf20Sopenharmony_ci exit 1 1868c2ecf20Sopenharmony_ci fi 1878c2ecf20Sopenharmony_ci} 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ciprog=$0 1908c2ecf20Sopenharmony_ciroot_uid=0 1918c2ecf20Sopenharmony_ciroot_gid=0 1928c2ecf20Sopenharmony_cidep_list= 1938c2ecf20Sopenharmony_cicpio_list=$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX) 1948c2ecf20Sopenharmony_cioutput="/dev/stdout" 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_citrap "rm -f $cpio_list" EXIT 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ciwhile [ $# -gt 0 ]; do 1998c2ecf20Sopenharmony_ci arg="$1" 2008c2ecf20Sopenharmony_ci shift 2018c2ecf20Sopenharmony_ci case "$arg" in 2028c2ecf20Sopenharmony_ci "-l") # files included in initramfs - used by kbuild 2038c2ecf20Sopenharmony_ci dep_list="$1" 2048c2ecf20Sopenharmony_ci echo "deps_initramfs := \\" > $dep_list 2058c2ecf20Sopenharmony_ci shift 2068c2ecf20Sopenharmony_ci ;; 2078c2ecf20Sopenharmony_ci "-o") # generate cpio image named $1 2088c2ecf20Sopenharmony_ci output="$1" 2098c2ecf20Sopenharmony_ci shift 2108c2ecf20Sopenharmony_ci ;; 2118c2ecf20Sopenharmony_ci "-u") # map $1 to uid=0 (root) 2128c2ecf20Sopenharmony_ci root_uid="$1" 2138c2ecf20Sopenharmony_ci [ "$root_uid" = "-1" ] && root_uid=$(id -u || echo 0) 2148c2ecf20Sopenharmony_ci shift 2158c2ecf20Sopenharmony_ci ;; 2168c2ecf20Sopenharmony_ci "-g") # map $1 to gid=0 (root) 2178c2ecf20Sopenharmony_ci root_gid="$1" 2188c2ecf20Sopenharmony_ci [ "$root_gid" = "-1" ] && root_gid=$(id -g || echo 0) 2198c2ecf20Sopenharmony_ci shift 2208c2ecf20Sopenharmony_ci ;; 2218c2ecf20Sopenharmony_ci "-h") 2228c2ecf20Sopenharmony_ci usage 2238c2ecf20Sopenharmony_ci exit 0 2248c2ecf20Sopenharmony_ci ;; 2258c2ecf20Sopenharmony_ci *) 2268c2ecf20Sopenharmony_ci case "$arg" in 2278c2ecf20Sopenharmony_ci "-"*) 2288c2ecf20Sopenharmony_ci unknown_option 2298c2ecf20Sopenharmony_ci ;; 2308c2ecf20Sopenharmony_ci *) # input file/dir - process it 2318c2ecf20Sopenharmony_ci input_file "$arg" 2328c2ecf20Sopenharmony_ci ;; 2338c2ecf20Sopenharmony_ci esac 2348c2ecf20Sopenharmony_ci ;; 2358c2ecf20Sopenharmony_ci esac 2368c2ecf20Sopenharmony_cidone 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci# If output_file is set we will generate cpio archive 2398c2ecf20Sopenharmony_ci# we are careful to delete tmp files 2408c2ecf20Sopenharmony_citimestamp= 2418c2ecf20Sopenharmony_ciif test -n "$KBUILD_BUILD_TIMESTAMP"; then 2428c2ecf20Sopenharmony_ci timestamp="$(date -d"$KBUILD_BUILD_TIMESTAMP" +%s || :)" 2438c2ecf20Sopenharmony_ci if test -n "$timestamp"; then 2448c2ecf20Sopenharmony_ci timestamp="-t $timestamp" 2458c2ecf20Sopenharmony_ci fi 2468c2ecf20Sopenharmony_cifi 2478c2ecf20Sopenharmony_ciusr/gen_init_cpio $timestamp $cpio_list > $output 248