mirror of
https://salsa.debian.org/kernel-team/initramfs-tools.git
synced 2026-01-26 15:39:08 +00:00
Create unmkinitramfs command
This command supports extracting files from an initramfs image. It is designed to be a drop-in for cpio wherever an initramfs may be present. It is implemented using the code from lsinitramfs, which now delegates to uninitramfs instead of cpio. Signed-off-by: Kevin Locke <kevin@kevinlocke.name> [bwh: Rename it from uninitramfs to unmkinitramfs; add to .install list] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
This commit is contained in:
parent
c48108dc0e
commit
f1f18a44fd
1
debian/initramfs-tools-core.install
vendored
1
debian/initramfs-tools-core.install
vendored
@ -1,4 +1,5 @@
|
||||
lsinitramfs usr/bin
|
||||
unmkinitramfs usr/bin
|
||||
init usr/share/initramfs-tools
|
||||
scripts usr/share/initramfs-tools
|
||||
conf/initramfs.conf etc/initramfs-tools
|
||||
|
||||
71
lsinitramfs
71
lsinitramfs
@ -12,7 +12,7 @@ if [ "$#" -eq 0 ] ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cpio_args="--extract --quiet --list"
|
||||
cpio_args="--quiet --list"
|
||||
|
||||
OPTIONS=`getopt -o hl --long help,long -n "$0" -- "$@"`
|
||||
# Check for non-GNU getopt
|
||||
@ -40,73 +40,6 @@ while true; do
|
||||
esac
|
||||
done
|
||||
|
||||
listarchive()
|
||||
{
|
||||
archive="$1"
|
||||
if zcat -t "${archive}" >/dev/null 2>&1 ; then
|
||||
zcat "${archive}" | cpio ${cpio_args}
|
||||
elif xzcat -t "${archive}" >/dev/null 2>&1 ; then
|
||||
xzcat "${archive}" | cpio ${cpio_args}
|
||||
elif bzip2 -t "${archive}" >/dev/null 2>&1 ; then
|
||||
bzip2 -c -d "${archive}" | cpio ${cpio_args}
|
||||
elif lzop -t "${archive}" >/dev/null 2>&1 ; then
|
||||
lzop -c -d "${archive}" | cpio ${cpio_args}
|
||||
fi
|
||||
}
|
||||
|
||||
# Read bytes out of a file, checking that they are valid hex digits
|
||||
readhex()
|
||||
{
|
||||
dd < "$1" bs=1 skip="$2" count="$3" 2> /dev/null | \
|
||||
LANG=C grep -E "^[0-9A-Fa-f]{$3}\$"
|
||||
}
|
||||
|
||||
# Check for a zero byte in a file
|
||||
checkzero()
|
||||
{
|
||||
dd < "$1" bs=1 skip="$2" count=1 2> /dev/null | \
|
||||
LANG=C grep -q -z '^$'
|
||||
}
|
||||
|
||||
for initramfs in "$@" ; do
|
||||
if ! [ -r "${initramfs}" ] ; then
|
||||
echo "Specified file could not be read." >&2
|
||||
exit 1
|
||||
else
|
||||
echo "${initramfs}"
|
||||
|
||||
# There may be a prepended uncompressed archive. cpio
|
||||
# won't tell us the true size of this so we have to
|
||||
# parse the headers and padding ourselves. This is
|
||||
# very roughly based on linux/lib/earlycpio.c
|
||||
offset=0
|
||||
while true; do
|
||||
if checkzero "$initramfs" $offset; then
|
||||
offset=$((offset + 4))
|
||||
continue
|
||||
fi
|
||||
magic="$(readhex "$initramfs" $offset 6)" || break
|
||||
test $magic = 070701 || test $magic = 070702 || break
|
||||
namesize=0x$(readhex "$initramfs" $((offset + 94)) 8)
|
||||
filesize=0x$(readhex "$initramfs" $((offset + 54)) 8)
|
||||
offset=$(((offset + 110)))
|
||||
offset=$(((offset + $namesize + 3) & ~3))
|
||||
offset=$(((offset + $filesize + 3) & ~3))
|
||||
done
|
||||
|
||||
if [ $offset -ne 0 ]; then
|
||||
# List uncompressed archive
|
||||
cpio ${cpio_args} < "$initramfs"
|
||||
|
||||
# List main archive
|
||||
subarchive=$(mktemp ${TMPDIR:-/var/tmp}/lsinitramfs_XXXXXX)
|
||||
trap "rm -f $subarchive" EXIT
|
||||
dd < "$initramfs" bs="$offset" skip=1 2> /dev/null \
|
||||
> $subarchive
|
||||
listarchive $subarchive
|
||||
else
|
||||
listarchive "${initramfs}"
|
||||
fi
|
||||
|
||||
fi
|
||||
unmkinitramfs $cpio_args < "$initramfs"
|
||||
done
|
||||
|
||||
@ -50,4 +50,5 @@ and numerous others.
|
||||
.BR
|
||||
.IR initramfs-tools (8),
|
||||
.IR mkinitramfs (8),
|
||||
.IR unmkinitramfs (8),
|
||||
.IR update-initramfs (8).
|
||||
|
||||
@ -155,4 +155,5 @@ Jeff Bailey <jbailey@raspberryginger.com> and numerous others.
|
||||
.IR initramfs.conf (5),
|
||||
.IR initramfs-tools (8),
|
||||
.IR update-initramfs (8),
|
||||
.IR lsinitramfs (8).
|
||||
.IR lsinitramfs (8),
|
||||
.IR unmkinitramfs (8).
|
||||
|
||||
99
unmkinitramfs
Executable file
99
unmkinitramfs
Executable file
@ -0,0 +1,99 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
usage()
|
||||
{
|
||||
echo "Usage: $(basename "$0") [cpio options ...] < <initramfs file>"
|
||||
}
|
||||
|
||||
# Abort if stdin is a terminal.
|
||||
#
|
||||
# Although cpio supports this, the chance of someone actually keying in a cpio
|
||||
# archive on the terminal is negligible compared to the risk of someone who
|
||||
# forgot cpio's arcane argument convention.
|
||||
if [ -t 0 ] ; then
|
||||
echo "Error: stdin must be an initramfs" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract a compressed cpio archive
|
||||
xcpio()
|
||||
{
|
||||
archive="$1" ; shift
|
||||
|
||||
if zcat -t "$archive" >/dev/null 2>&1 ; then
|
||||
zcat "$archive" | cpio "$@"
|
||||
elif xzcat -t "$archive" >/dev/null 2>&1 ; then
|
||||
xzcat "$archive" | cpio "$@"
|
||||
elif bzip2 -t "$archive" >/dev/null 2>&1 ; then
|
||||
bzip2 -c -d "$archive" | cpio "$@"
|
||||
elif lzop -t "$archive" >/dev/null 2>&1 ; then
|
||||
lzop -c -d "$archive" | cpio "$@"
|
||||
# Ignoring other data, which may be garbage at the end of the file
|
||||
fi
|
||||
}
|
||||
|
||||
# Read bytes out of a file, checking that they are valid hex digits
|
||||
readhex()
|
||||
{
|
||||
dd < "$1" bs=1 skip="$2" count="$3" 2> /dev/null | \
|
||||
LANG=C grep -E "^[0-9A-Fa-f]{$3}\$"
|
||||
}
|
||||
|
||||
# Check for a zero byte in a file
|
||||
checkzero()
|
||||
{
|
||||
dd < "$1" bs=1 skip="$2" count=1 2> /dev/null | \
|
||||
LANG=C grep -q -z '^$'
|
||||
}
|
||||
|
||||
# Split an initramfs into archives and call xcpio on each
|
||||
splitinitramfs()
|
||||
{
|
||||
initramfs="$1" ; shift
|
||||
|
||||
# There may be a prepended uncompressed archive. cpio
|
||||
# won't tell us the true size of this so we have to
|
||||
# parse the headers and padding ourselves. This is
|
||||
# very roughly based on linux/lib/earlycpio.c
|
||||
offset=0
|
||||
while true; do
|
||||
if checkzero "$initramfs" $offset; then
|
||||
offset=$((offset + 4))
|
||||
continue
|
||||
fi
|
||||
magic="$(readhex "$initramfs" $offset 6)" || break
|
||||
test $magic = 070701 || test $magic = 070702 || break
|
||||
namesize=0x$(readhex "$initramfs" $((offset + 94)) 8)
|
||||
filesize=0x$(readhex "$initramfs" $((offset + 54)) 8)
|
||||
offset=$(((offset + 110)))
|
||||
offset=$(((offset + $namesize + 3) & ~3))
|
||||
offset=$(((offset + $filesize + 3) & ~3))
|
||||
done
|
||||
|
||||
if [ $offset -ne 0 ]; then
|
||||
# uncompressed archive
|
||||
cpio -i "$@" < "$initramfs"
|
||||
|
||||
# main archive
|
||||
subarchive=$(mktemp ${TMPDIR:-/var/tmp}/unmkinitramfs_XXXXXX)
|
||||
trap "rm -f '$subarchive'" EXIT
|
||||
dd < "$initramfs" bs="$offset" skip=1 2> /dev/null \
|
||||
> $subarchive
|
||||
xcpio "$subarchive" -i "$@"
|
||||
else
|
||||
xcpio "$initramfs" -i "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# If we can get the name of the file passed in, use it. Otherwise, create one.
|
||||
stdin_filename=$(readlink /proc/$$/fd/0 2>/dev/null || true)
|
||||
if ! [ -r "$stdin_filename" ] ; then
|
||||
stdin_filename=$(mktemp ${TMPDIR:-/var/tmp}/uninitramfs_stdin_XXXXXX)
|
||||
trap "rm -f '$stdin_filename'" EXIT
|
||||
cat > "$stdin_filename"
|
||||
fi
|
||||
|
||||
splitinitramfs "$stdin_filename" "$@"
|
||||
59
unmkinitramfs.8
Normal file
59
unmkinitramfs.8
Normal file
@ -0,0 +1,59 @@
|
||||
.TH UNMKINITRAMFS 8 "2016/02/09" "Linux" "unmkinitramfs manual"
|
||||
|
||||
.SH NAME
|
||||
unmkinitramfs \- extract content from an initramfs image
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B unmkinitramfs
|
||||
.RI "" "[cpio options ...]" " < " <initramfsfile>
|
||||
.br
|
||||
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B unmkinitramfs
|
||||
command extracts the content of a given initramfs image using
|
||||
.BR cpio .
|
||||
If the image contains multiple segments, each are passed to
|
||||
.B cpio
|
||||
in order.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
All options are passed through to
|
||||
.B cpio
|
||||
, after an initial
|
||||
.B \-i
|
||||
option which puts
|
||||
.B cpio
|
||||
into \*(lqextract\*(rq or \*(lqCopy-in\*(rq mode.
|
||||
|
||||
.SH USAGE EXAMPLES
|
||||
|
||||
Extract initramfs content of current running kernel:
|
||||
|
||||
.PP
|
||||
.B unmkinitramfs < /boot/initrd.img-$(uname -r)
|
||||
|
||||
Extract
|
||||
.I init
|
||||
from the initramfs verbosely and keep its mtime:
|
||||
|
||||
.PP
|
||||
.B unmkinitramfs -m -v init < /boot/initrd.img-$(uname -r)
|
||||
|
||||
.SH BUGS
|
||||
.BR unmkinitramfs
|
||||
cannot deal with multiple-segmented initramfs images, except where an
|
||||
early (uncompressed) initramfs with system firmware is prepended to
|
||||
the regular compressed initramfs.
|
||||
|
||||
.SH AUTHOR
|
||||
The initramfs-tools are written by Maximilian Attems <maks@debian.org>
|
||||
and numerous others.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR
|
||||
.IR initramfs-tools (8),
|
||||
.IR lsinitramfs (8),
|
||||
.IR mkinitramfs (8),
|
||||
.IR update-initramfs (8).
|
||||
Loading…
x
Reference in New Issue
Block a user