mirror of
https://salsa.debian.org/kernel-team/initramfs-tools.git
synced 2026-01-26 15:39:08 +00:00
Merge branch 'unmk-regression' into 'debian/latest'
unmkinitramfs: Restore split to "early" and "main" subdirectories See merge request kernel-team/initramfs-tools!162
This commit is contained in:
commit
8722bb830a
143
unmkinitramfs
143
unmkinitramfs
@ -25,24 +25,28 @@ usage_error()
|
||||
# Extract a compressed cpio archive
|
||||
xcpio()
|
||||
{
|
||||
archive="$1"
|
||||
dir="$2"
|
||||
shift 2
|
||||
archive_uncomp="$1"
|
||||
archive="$2"
|
||||
dir="$3"
|
||||
shift 3
|
||||
|
||||
if gzip -t "$archive" >/dev/null 2>&1 ; then
|
||||
gzip -c -d "$archive"
|
||||
elif zstd -q -c -t "$archive" >/dev/null 2>&1 ; then
|
||||
zstd -q -c -d "$archive"
|
||||
elif xzcat -t "$archive" >/dev/null 2>&1 ; then
|
||||
xzcat "$archive"
|
||||
elif lz4cat -t < "$archive" >/dev/null 2>&1 ; then
|
||||
lz4cat "$archive"
|
||||
elif bzip2 -t "$archive" >/dev/null 2>&1 ; then
|
||||
bzip2 -c -d "$archive"
|
||||
elif lzop -t "$archive" >/dev/null 2>&1 ; then
|
||||
lzop -c -d "$archive"
|
||||
# Ignoring other data, which may be garbage at the end of the file
|
||||
fi | (
|
||||
{
|
||||
cat "$archive_uncomp"
|
||||
if gzip -t "$archive" >/dev/null 2>&1 ; then
|
||||
gzip -c -d "$archive"
|
||||
elif zstd -q -c -t "$archive" >/dev/null 2>&1 ; then
|
||||
zstd -q -c -d "$archive"
|
||||
elif xzcat -t "$archive" >/dev/null 2>&1 ; then
|
||||
xzcat "$archive"
|
||||
elif lz4cat -t < "$archive" >/dev/null 2>&1 ; then
|
||||
lz4cat "$archive"
|
||||
elif bzip2 -t "$archive" >/dev/null 2>&1 ; then
|
||||
bzip2 -c -d "$archive"
|
||||
elif lzop -t "$archive" >/dev/null 2>&1 ; then
|
||||
lzop -c -d "$archive"
|
||||
# Ignoring other data, which may be garbage at the end of the file
|
||||
fi
|
||||
} | (
|
||||
if [ -n "$dir" ]; then
|
||||
mkdir -p -- "$dir"
|
||||
cd -- "$dir"
|
||||
@ -65,13 +69,16 @@ checkzero()
|
||||
LANG=C grep -q -z '^$'
|
||||
}
|
||||
|
||||
# Split an initramfs into archives and call xcpio on each
|
||||
# Split an initramfs into archives and run cpio/xcpio to extract them
|
||||
splitinitramfs()
|
||||
{
|
||||
initramfs="$1"
|
||||
dir="$2"
|
||||
shift 2
|
||||
|
||||
# Ensure this exists so we can use it unconditionally later
|
||||
touch "$tempdir/main-uncomp.cpio"
|
||||
|
||||
count=0
|
||||
start=0
|
||||
while true; do
|
||||
@ -81,55 +88,92 @@ splitinitramfs()
|
||||
# very roughly based on linux/lib/earlycpio.c
|
||||
end=$start
|
||||
while true; do
|
||||
if checkzero "$initramfs" $end; then
|
||||
# This is the EOF marker. There might
|
||||
# be more zero padding before the next
|
||||
# archive, so read through all of it.
|
||||
end=$((end + 4))
|
||||
headoff=$end
|
||||
magic="$(readhex "$initramfs" $end 6)" || break
|
||||
test "$magic" = 070701 || test "$magic" = 070702 || break
|
||||
namesize=$((0x$(readhex "$initramfs" $((end + 94)) 8)))
|
||||
filesize=$((0x$(readhex "$initramfs" $((end + 54)) 8)))
|
||||
nameoff=$((end + 110))
|
||||
end=$(((nameoff + namesize + 3) & ~3))
|
||||
end=$(((end + filesize + 3) & ~3))
|
||||
|
||||
# Check for EOF marker. Note that namesize
|
||||
# includes a null terminator.
|
||||
if [ $namesize = 11 ] \
|
||||
&& name="$(dd if="$initramfs" bs=1 skip=$nameoff count=$((namesize - 1)) 2> /dev/null)" \
|
||||
&& [ "$name" = 'TRAILER!!!' ]; then
|
||||
# There might be more zero padding
|
||||
# before the next archive, so read
|
||||
# through all of it.
|
||||
while checkzero "$initramfs" $end; do
|
||||
end=$((end + 4))
|
||||
done
|
||||
break
|
||||
fi
|
||||
magic="$(readhex "$initramfs" $end 6)" || break
|
||||
test "$magic" = 070701 || test "$magic" = 070702 || break
|
||||
namesize=0x$(readhex "$initramfs" $((end + 94)) 8)
|
||||
filesize=0x$(readhex "$initramfs" $((end + 54)) 8)
|
||||
end=$((end + 110))
|
||||
end=$(((end + namesize + 3) & ~3))
|
||||
end=$(((end + filesize + 3) & ~3))
|
||||
done
|
||||
|
||||
if [ $end -eq $start ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
# Extract to cpio1, cpio2, ... subdirectories
|
||||
count=$((count + 1))
|
||||
subdir=cpio$count
|
||||
dd < "$initramfs" skip=$start count=$((end - start)) iflag=skip_bytes,count_bytes 2> /dev/null |
|
||||
(
|
||||
if [ -n "$dir" ]; then
|
||||
mkdir -p -- "$dir/$subdir"
|
||||
cd -- "$dir/$subdir"
|
||||
# Check whether this should be treated as an "early"
|
||||
# or "main" initramfs. Currently all filenames the
|
||||
# kernel looks for in an early initramfs begin with
|
||||
# kernel/ subdirectory, but we should never create
|
||||
# this in the main initramfs.
|
||||
if dd < "$initramfs" skip=$start count=$((end - start)) \
|
||||
iflag=skip_bytes,count_bytes 2> /dev/null |
|
||||
cpio -i --list 2> /dev/null |
|
||||
grep -q ^kernel/; then
|
||||
# Extract to early, early2, ... subdirectories
|
||||
count=$((count + 1))
|
||||
if [ $count -eq 1 ]; then
|
||||
subdir=early
|
||||
else
|
||||
subdir=early$count
|
||||
fi
|
||||
cpio -i "$@"
|
||||
)
|
||||
dd < "$initramfs" skip=$start count=$((end - start)) \
|
||||
iflag=skip_bytes,count_bytes 2> /dev/null |
|
||||
(
|
||||
if [ -n "$dir" ]; then
|
||||
mkdir -p -- "$dir/$subdir"
|
||||
cd -- "$dir/$subdir"
|
||||
fi
|
||||
cpio -i "$@"
|
||||
)
|
||||
else
|
||||
# Append to main-uncomp.cpio, excluding the
|
||||
# trailer so cpio won't stop before the
|
||||
# (de)compressed part.
|
||||
dd < "$initramfs" skip=$start \
|
||||
count=$((headoff - start)) \
|
||||
iflag=skip_bytes,count_bytes \
|
||||
>> "$tempdir/main-uncomp.cpio" 2> /dev/null
|
||||
fi
|
||||
|
||||
start=$end
|
||||
done
|
||||
|
||||
# Split out final archive if necessary
|
||||
if [ "$end" -gt 0 ]; then
|
||||
# Extract to main subdirectory
|
||||
subarchive=$(mktemp "${TMPDIR:-/var/tmp}/unmkinitramfs_XXXXXX")
|
||||
trap 'rm -f "$subarchive"' EXIT
|
||||
subarchive="$tempdir/main-comp.cpio"
|
||||
dd < "$initramfs" skip="$end" iflag=skip_bytes 2> /dev/null \
|
||||
> "$subarchive"
|
||||
count=$((count + 1))
|
||||
subdir=cpio$count
|
||||
xcpio "$subarchive" "${dir:+$dir/$subdir}" -i "$@"
|
||||
else
|
||||
# Don't use subdirectories (for backward compatibility)
|
||||
xcpio "$initramfs" "$dir" -i "$@"
|
||||
subarchive="$initramfs"
|
||||
fi
|
||||
|
||||
# If we found an early initramfs, extract main initramfs to
|
||||
# main subdirectory. Otherwise don't use a subdirectory (for
|
||||
# backward compatibility).
|
||||
if [ "$count" -gt 0 ]; then
|
||||
subdir=main
|
||||
else
|
||||
subdir=.
|
||||
fi
|
||||
|
||||
xcpio "$tempdir/main-uncomp.cpio" "$subarchive" \
|
||||
"${dir:+$dir/$subdir}" -i "$@"
|
||||
}
|
||||
|
||||
OPTIONS=$(getopt -o hv --long help,list,verbose -n "$0" -- "$@") || usage_error
|
||||
@ -168,5 +212,8 @@ if [ $# -ne $expected_args ]; then
|
||||
usage_error
|
||||
fi
|
||||
|
||||
tempdir="$(mktemp -d "${TMPDIR:-/var/tmp}/unmkinitramfs_XXXXXX")"
|
||||
trap 'rm -rf "$tempdir"' EXIT
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
splitinitramfs "$1" "${2:-}" $cpio_opts
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
.TH UNMKINITRAMFS 8 "2016/12/15" "initramfs\-tools" "System Administration"
|
||||
.TH UNMKINITRAMFS 8 "2025/03/20" "initramfs\-tools" "System Administration"
|
||||
|
||||
.SH NAME
|
||||
unmkinitramfs \- extract content from an initramfs image
|
||||
@ -14,10 +14,21 @@ unmkinitramfs \- extract content from an initramfs image
|
||||
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.
|
||||
and the appropriate decompressor command.
|
||||
|
||||
The initramfs image may be a single compressed cpio archive, or the
|
||||
concatenation of any number of uncompressed cpio archives followed by
|
||||
a compressed cpio archive.
|
||||
|
||||
When the initramfs image includes one or more "early initramfs"
|
||||
archives, that is uncompressed archives with microcode or other files
|
||||
that the kernel uses directly, these are extracted to sub\-directories
|
||||
named "\fBearly\fR", "\fBearly2\fR", etc., and the other archives are
|
||||
extracted to a sub\-directory named "\fBmain\fR".
|
||||
|
||||
In a future version of initramfs\-tools this behaviour may change so
|
||||
that all archives are extracted directly into the given directory.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
@ -40,9 +51,8 @@ Extract initramfs content of current running kernel:
|
||||
|
||||
.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.
|
||||
does not support initramfs images with more or less than one
|
||||
compressed cpio archive.
|
||||
|
||||
.SH AUTHOR
|
||||
The initramfs-tools are written by Maximilian Attems <maks@debian.org>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user