Skip to content

Instantly share code, notes, and snippets.

@tai271828
Forked from smoser/README.md
Created October 22, 2020 13:31
Show Gist options
  • Save tai271828/123c2d16b3d570720892c2ac641ca65e to your computer and use it in GitHub Desktop.
Save tai271828/123c2d16b3d570720892c2ac641ca65e to your computer and use it in GitHub Desktop.
update or add to an initramfs or initrd with contents of a directory

Update an initramfs with contents of a directory without root

This tool allows you to take a initramfs and add contents of a directory to it. This is very useful if you need to test initramfs, you can simply take the original and add your files "over".

Also, because it does not extract the original cpio archive, it works without root.

Usage:

Usage: overlay-initramfs [ options ] source-initramfs directory [output]

   create an initramfs that has 'directory' overlayed on top
   of the source-initramfs.  This relies on the fact that you can
   append cpio archives to an initramfs and the kernel extraction
   just puts one on top of the other.

Notes

  • This probably needs to be updated with the new style initramfs that have an 'early' and 'early2' directory in them. In newer ubuntu (18.04+) there is a tool 'unmkinitramfs' that unpacks initramfs, but unfortunately there is no "re-initramfs" that would re-pack the unmkinitramfs output.
#!/bin/bash
VERBOSITY=0
TEMP_D=""
error() { echo "$@" 1>&2; }
fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
Usage() {
cat <<EOF
Usage: ${0##*/} [ options ] source-initramfs directory [output]
create an initramfs that has 'directory' overlayed on top
of the source-initramfs. This relies on the fact that you can
append cpio archives to an initramfs and the kernel extraction
just puts one on top of the other.
EOF
}
bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; exit 1; }
cleanup() {
[ -z "${TEMP_D}" -o ! -d "${TEMP_D}" ] || rm -Rf "${TEMP_D}"
}
debug() {
local level=${1}; shift;
[ "${level}" -gt "${VERBOSITY}" ] && return
error "${@}"
}
short_opts="hv"
long_opts="help,verbose"
getopt_out=$(getopt --name "${0##*/}" \
--options "${short_opts}" --long "${long_opts}" -- "$@") &&
eval set -- "${getopt_out}" ||
bad_Usage
output="-"
while [ $# -ne 0 ]; do
cur=${1}; next=${2};
case "$cur" in
-h|--help) Usage ; exit 0;;
-v|--verbose) VERBOSITY=$((${VERBOSITY}+1));;
--) shift; break;;
esac
shift;
done
[ $# -ge 1 -a $# -le 3 ] ||
bad_Usage "must give between 1 and 3 arguments"
orig="$1"
add_d="$2"
[ -f "$orig" ] || fail "${orig}: not a file"
[ -d "${add_d}" ] || fail "${add_d}: not a directory"
[ $# -eq 3 ] && output="$3"
TEMP_D=$(mktemp -d "${TMPDIR:-/tmp}/${0##*/}.XXXXXX") ||
fail "failed to make tempdir"
trap cleanup EXIT
start="$PWD"
cd "${add_d}" || fail "failed to chdir to ${add_d}"
find . > "${TEMP_D}/files" ||
fail "failed to get file list in ${add_d}"
cpio --format=newc -o > "${TEMP_D}/update.cpio" < "${TEMP_D}/files" ||
fail "failed to create update cpio"
cd "$start"
if [ "$output" = "-" ]; then
exec 3>&1
else
exec 3>"$output"
fi
[ $? -eq 0 ] || fail "failed redirect output"
set -o pipefail
( zcat "$orig" && cat "${TEMP_D}/update.cpio" ) | gzip -c >&3 ||
fail "failed to write to $output"
error "wrote to $output"
# vi: ts=4 noexpandtab
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment