]>
Commit | Line | Data |
---|---|---|
3b403b32 | 1 | #!/bin/bash |
cc02093d HH |
2 | # |
3 | # Copyright 2005-2010 Harald Hoyer <harald@redhat.com> | |
4 | # Copyright 2005-2010 Red Hat, Inc. All rights reserved. | |
5 | # | |
6 | # This program is free software; you can redistribute it and/or modify | |
7 | # it under the terms of the GNU General Public License as published by | |
8 | # the Free Software Foundation; either version 2 of the License, or | |
9 | # (at your option) any later version. | |
10 | # | |
11 | # This program is distributed in the hope that it will be useful, | |
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | # GNU General Public License for more details. | |
15 | # | |
16 | # You should have received a copy of the GNU General Public License | |
17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | # | |
074d12c1 | 19 | |
9a52c3fd | 20 | usage() { |
dde2db3d | 21 | { |
7d9bb76a HH |
22 | echo "Usage: ${0##*/} [options] [<initramfs file> [<filename> [<filename> [...] ]]]" |
23 | echo "Usage: ${0##*/} [options] -k <kernel version>" | |
dde2db3d | 24 | echo |
7d9bb76a HH |
25 | echo "-h, --help print a help message and exit." |
26 | echo "-s, --size sort the contents of the initramfs by size." | |
05d2a145 | 27 | echo "-m, --mod list modules." |
7d9bb76a | 28 | echo "-f, --file <filename> print the contents of <filename>." |
97bbba69 | 29 | echo "--unpack unpack the initramfs, instead of displaying the contents." |
143420bc KS |
30 | echo " If optional filenames are given, will only unpack specified files," |
31 | echo " else the whole image will be unpacked. Won't unpack anything from early cpio part." | |
97bbba69 | 32 | echo "--unpackearly unpack the early microcode part of the initramfs." |
143420bc | 33 | echo " Same as --unpack, but only unpack files from early cpio part." |
97bbba69 | 34 | echo "-v, --verbose unpack verbosely." |
7d9bb76a | 35 | echo "-k, --kver <kernel version> inspect the initramfs of <kernel version>." |
dde2db3d HH |
36 | echo |
37 | } >&2 | |
f7bccf37 HH |
38 | } |
39 | ||
b208aad5 HH |
40 | [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut |
41 | ||
3ea5d2e2 | 42 | sorted=0 |
05d2a145 | 43 | modules=0 |
97bbba69 | 44 | unset verbose |
7d9bb76a HH |
45 | declare -A filenames |
46 | ||
47 | unset POSIXLY_CORRECT | |
48 | TEMP=$(getopt \ | |
97bbba69 | 49 | -o "vshmf:k:" \ |
7d9bb76a HH |
50 | --long kver: \ |
51 | --long file: \ | |
05d2a145 | 52 | --long mod \ |
7d9bb76a HH |
53 | --long help \ |
54 | --long size \ | |
97bbba69 HH |
55 | --long unpack \ |
56 | --long unpackearly \ | |
57 | --long verbose \ | |
7d9bb76a HH |
58 | -- "$@") |
59 | ||
0ce54e80 | 60 | # shellcheck disable=SC2181 |
9a52c3fd | 61 | if (($? != 0)); then |
7d9bb76a HH |
62 | usage |
63 | exit 1 | |
64 | fi | |
65 | ||
66 | eval set -- "$TEMP" | |
67 | ||
68 | while (($# > 0)); do | |
69 | case $1 in | |
9a52c3fd HH |
70 | -k | --kver) |
71 | KERNEL_VERSION="$2" | |
72 | shift | |
73 | ;; | |
74 | -f | --file) | |
75 | filenames[${2#/}]=1 | |
76 | shift | |
77 | ;; | |
78 | -s | --size) sorted=1 ;; | |
79 | -h | --help) | |
80 | usage | |
81 | exit 0 | |
82 | ;; | |
83 | -m | --mod) modules=1 ;; | |
84 | -v | --verbose) verbose="--verbose" ;; | |
85 | --unpack) unpack=1 ;; | |
86 | --unpackearly) unpackearly=1 ;; | |
87 | --) | |
88 | shift | |
89 | break | |
90 | ;; | |
91 | *) | |
92 | usage | |
93 | exit 1 | |
94 | ;; | |
3ea5d2e2 | 95 | esac |
7d9bb76a | 96 | shift |
3ea5d2e2 | 97 | done |
3ea5d2e2 | 98 | |
7d9bb76a | 99 | [[ $KERNEL_VERSION ]] || KERNEL_VERSION="$(uname -r)" |
dde2db3d | 100 | |
7d9bb76a | 101 | if [[ $1 ]]; then |
dde2db3d | 102 | image="$1" |
75d758e8 | 103 | if ! [[ -f $image ]]; then |
dde2db3d HH |
104 | { |
105 | echo "$image does not exist" | |
106 | echo | |
107 | } >&2 | |
108 | usage | |
109 | exit 1 | |
110 | fi | |
dde2db3d | 111 | else |
49ea6c42 AAF |
112 | if [[ -d /efi/Default ]] || [[ -d /boot/Default ]] || [[ -d /boot/efi/Default ]]; then |
113 | MACHINE_ID="Default" | |
114 | elif [[ -f /etc/machine-id ]]; then | |
115 | read -r MACHINE_ID < /etc/machine-id | |
116 | else | |
117 | MACHINE_ID="Default" | |
118 | fi | |
727e68d0 | 119 | |
093bc9b5 JG |
120 | if [[ -d /efi/loader/entries || -L /efi/loader/entries ]] \ |
121 | && [[ $MACHINE_ID ]] \ | |
9a52c3fd | 122 | && [[ -d /efi/${MACHINE_ID} || -L /efi/${MACHINE_ID} ]]; then |
093bc9b5 JG |
123 | image="/efi/${MACHINE_ID}/${KERNEL_VERSION}/initrd" |
124 | elif [[ -d /boot/loader/entries || -L /boot/loader/entries ]] \ | |
7d9bb76a | 125 | && [[ $MACHINE_ID ]] \ |
9a52c3fd | 126 | && [[ -d /boot/${MACHINE_ID} || -L /boot/${MACHINE_ID} ]]; then |
727e68d0 | 127 | image="/boot/${MACHINE_ID}/${KERNEL_VERSION}/initrd" |
49ea6c42 AAF |
128 | elif [[ -d /boot/efi/loader/entries || -L /boot/efi/loader/entries ]] \ |
129 | && [[ $MACHINE_ID ]] \ | |
130 | && [[ -d /boot/efi/${MACHINE_ID} || -L /boot/efi/${MACHINE_ID} ]]; then | |
131 | image="/boot/efi/${MACHINE_ID}/${KERNEL_VERSION}/initrd" | |
132 | elif [[ -f /lib/modules/${KERNEL_VERSION}/initrd ]]; then | |
133 | image="/lib/modules/${KERNEL_VERSION}/initrd" | |
e877be69 K |
134 | elif [[ -f /lib/modules/${KERNEL_VERSION}/initramfs.img ]]; then |
135 | image="/lib/modules/${KERNEL_VERSION}/initramfs.img" | |
49ea6c42 | 136 | elif [[ -f /boot/initramfs-${KERNEL_VERSION}.img ]]; then |
d928724c | 137 | image="/boot/initramfs-${KERNEL_VERSION}.img" |
d6343146 AAF |
138 | elif [[ $MACHINE_ID ]] \ |
139 | && mountpoint -q /efi; then | |
49ea6c42 | 140 | image="/efi/${MACHINE_ID}/${KERNEL_VERSION}/initrd" |
d6343146 AAF |
141 | elif [[ $MACHINE_ID ]] \ |
142 | && mountpoint -q /boot/efi; then | |
49ea6c42 AAF |
143 | image="/boot/efi/${MACHINE_ID}/${KERNEL_VERSION}/initrd" |
144 | else | |
145 | image="" | |
727e68d0 | 146 | fi |
dde2db3d HH |
147 | fi |
148 | ||
7d9bb76a HH |
149 | shift |
150 | while (($# > 0)); do | |
9a52c3fd | 151 | filenames[${1#/}]=1 |
7d9bb76a HH |
152 | shift |
153 | done | |
727e68d0 | 154 | |
75d758e8 | 155 | if ! [[ -f $image ]]; then |
dde2db3d HH |
156 | { |
157 | echo "No <initramfs file> specified and the default image '$image' cannot be accessed!" | |
158 | echo | |
159 | } >&2 | |
160 | usage | |
161 | exit 1 | |
162 | fi | |
074d12c1 | 163 | |
cbf32008 | 164 | TMPDIR="$(mktemp -d -t lsinitrd.XXXXXX)" |
0ce54e80 | 165 | # shellcheck disable=SC2064 |
cbf32008 MR |
166 | trap "rm -rf '$TMPDIR'" EXIT |
167 | ||
d3be9275 AŻ |
168 | dracutlibdirs() { |
169 | for d in lib64/dracut lib/dracut usr/lib64/dracut usr/lib/dracut; do | |
170 | echo "$d/$1" | |
171 | done | |
172 | } | |
173 | ||
9a52c3fd HH |
174 | extract_files() { |
175 | ((${#filenames[@]} == 1)) && nofileinfo=1 | |
3721635b | 176 | for f in "${!filenames[@]}"; do |
b208aad5 HH |
177 | [[ $nofileinfo ]] || echo "initramfs:/$f" |
178 | [[ $nofileinfo ]] || echo "========================================================================" | |
1f84ff88 AAF |
179 | # shellcheck disable=SC2001 |
180 | [[ $f == *"\\x"* ]] && f=$(echo "$f" | sed 's/\\x.\{2\}/????/g') | |
9a52c3fd HH |
181 | $CAT "$image" 2> /dev/null | cpio --extract --verbose --quiet --to-stdout "$f" 2> /dev/null |
182 | ((ret += $?)) | |
b208aad5 HH |
183 | [[ $nofileinfo ]] || echo "========================================================================" |
184 | [[ $nofileinfo ]] || echo | |
185 | done | |
186 | } | |
187 | ||
9a52c3fd | 188 | list_modules() { |
05d2a145 | 189 | echo "dracut modules:" |
0ce54e80 | 190 | # shellcheck disable=SC2046 |
d3be9275 | 191 | $CAT "$image" | cpio --extract --verbose --quiet --to-stdout -- \ |
9a52c3fd HH |
192 | $(dracutlibdirs modules.txt) 2> /dev/null |
193 | ((ret += $?)) | |
05d2a145 HB |
194 | } |
195 | ||
9a52c3fd | 196 | list_files() { |
b208aad5 HH |
197 | echo "========================================================================" |
198 | if [ "$sorted" -eq 1 ]; then | |
9a52c3fd | 199 | $CAT "$image" 2> /dev/null | cpio --extract --verbose --quiet --list | sort -n -k5 |
b208aad5 | 200 | else |
9a52c3fd | 201 | $CAT "$image" 2> /dev/null | cpio --extract --verbose --quiet --list | sort -k9 |
b208aad5 | 202 | fi |
9a52c3fd | 203 | ((ret += $?)) |
b208aad5 HH |
204 | echo "========================================================================" |
205 | } | |
206 | ||
9a52c3fd | 207 | list_squash_content() { |
8f7c332e | 208 | SQUASH_IMG="squash-root.img" |
cbf32008 MR |
209 | SQUASH_TMPFILE="$TMPDIR/initrd.root.sqsh" |
210 | ||
9a52c3fd HH |
211 | $CAT "$image" 2> /dev/null | cpio --extract --verbose --quiet --to-stdout -- \ |
212 | $SQUASH_IMG > "$SQUASH_TMPFILE" 2> /dev/null | |
1ff306a3 KS |
213 | if [[ -s $SQUASH_TMPFILE ]]; then |
214 | echo "Squashed content ($SQUASH_IMG):" | |
215 | echo "========================================================================" | |
216 | unsquashfs -ll "$SQUASH_TMPFILE" | tail -n +4 | |
217 | echo "========================================================================" | |
218 | fi | |
219 | } | |
220 | ||
9a52c3fd HH |
221 | unpack_files() { |
222 | if ((${#filenames[@]} > 0)); then | |
f81c864e | 223 | for f in "${!filenames[@]}"; do |
1f84ff88 AAF |
224 | # shellcheck disable=SC2001 |
225 | [[ $f == *"\\x"* ]] && f=$(echo "$f" | sed 's/\\x.\{2\}/????/g') | |
226 | $CAT "$image" 2> /dev/null | cpio -id --quiet $verbose "$f" | |
9a52c3fd | 227 | ((ret += $?)) |
f81c864e KS |
228 | done |
229 | else | |
9a52c3fd HH |
230 | $CAT "$image" 2> /dev/null | cpio -id --quiet $verbose |
231 | ((ret += $?)) | |
f81c864e | 232 | fi |
97bbba69 HH |
233 | } |
234 | ||
0ce54e80 | 235 | read -r -N 2 bin < "$image" |
cbf32008 | 236 | if [ "$bin" = "MZ" ]; then |
9a52c3fd HH |
237 | command -v objcopy > /dev/null || { |
238 | echo "Need 'objcopy' to unpack an UEFI executable." | |
239 | exit 1 | |
240 | } | |
cbf32008 MR |
241 | objcopy \ |
242 | --dump-section .linux="$TMPDIR/vmlinuz" \ | |
243 | --dump-section .initrd="$TMPDIR/initrd.img" \ | |
244 | --dump-section .cmdline="$TMPDIR/cmdline.txt" \ | |
245 | --dump-section .osrel="$TMPDIR/osrel.txt" \ | |
246 | "$image" /dev/null | |
247 | uefi="$image" | |
248 | image="$TMPDIR/initrd.img" | |
249 | [ -f "$image" ] || exit 1 | |
250 | fi | |
b208aad5 | 251 | |
75d758e8 | 252 | if ((${#filenames[@]} <= 0)) && [[ -z $unpack ]] && [[ -z $unpackearly ]]; then |
32dfd416 | 253 | if [ -n "$uefi" ]; then |
cbf32008 | 254 | echo -n "initrd in UEFI: $uefi: " |
0ce54e80 | 255 | du -h "$image" | while read -r a _ || [ -n "$a" ]; do echo "$a"; done |
cbf32008 MR |
256 | if [ -f "$TMPDIR/osrel.txt" ]; then |
257 | name=$(sed -En '/^PRETTY_NAME/ s/^\w+=["'"'"']?([^"'"'"'$]*)["'"'"']?/\1/p' "$TMPDIR/osrel.txt") | |
258 | id=$(sed -En '/^ID/ s/^\w+=["'"'"']?([^"'"'"'$]*)["'"'"']?/\1/p' "$TMPDIR/osrel.txt") | |
259 | build=$(sed -En '/^BUILD_ID/ s/^\w+=["'"'"']?([^"'"'"'$]*)["'"'"']?/\1/p' "$TMPDIR/osrel.txt") | |
260 | echo "OS Release: $name (${id}-${build})" | |
261 | fi | |
262 | if [ -f "$TMPDIR/vmlinuz" ]; then | |
263 | version=$(strings -n 20 "$TMPDIR/vmlinuz" | sed -En '/[0-9]+\.[0-9]+\.[0-9]+/ { p; q 0 }') | |
264 | echo "Kernel Version: $version" | |
265 | fi | |
266 | if [ -f "$TMPDIR/cmdline.txt" ]; then | |
267 | echo "Command line:" | |
268 | sed -En 's/\s+/\n/g; s/\x00/\n/; p' "$TMPDIR/cmdline.txt" | |
269 | fi | |
270 | else | |
271 | echo -n "Image: $image: " | |
0ce54e80 | 272 | du -h "$image" | while read -r a _ || [ -n "$a" ]; do echo "$a"; done |
cbf32008 MR |
273 | fi |
274 | ||
b208aad5 HH |
275 | echo "========================================================================" |
276 | fi | |
277 | ||
0ce54e80 | 278 | read -r -N 6 bin < "$image" |
b208aad5 | 279 | case $bin in |
9a52c3fd | 280 | $'\x71\xc7'* | 070701) |
18a5011f | 281 | CAT="cat --" |
9a52c3fd | 282 | is_early=$(cpio --extract --verbose --quiet --to-stdout -- 'early_cpio' < "$image" 2> /dev/null) |
ce62465c | 283 | # Debian mkinitramfs does not create the file 'early_cpio', so let's check if firmware files exist |
9a52c3fd | 284 | [[ "$is_early" ]] || is_early=$(cpio --list --verbose --quiet --to-stdout -- 'kernel/*/microcode/*.bin' < "$image" 2> /dev/null) |
b208aad5 | 285 | if [[ "$is_early" ]]; then |
75d758e8 | 286 | if [[ -n $unpack ]]; then |
f81c864e KS |
287 | # should use --unpackearly for early CPIO |
288 | : | |
75d758e8 | 289 | elif [[ -n $unpackearly ]]; then |
97bbba69 | 290 | unpack_files |
9a52c3fd | 291 | elif ((${#filenames[@]} > 0)); then |
b208aad5 HH |
292 | extract_files |
293 | else | |
294 | echo "Early CPIO image" | |
295 | list_files | |
296 | fi | |
5eb996a9 AAF |
297 | if [[ -d "$dracutbasedir/src/skipcpio" ]]; then |
298 | SKIP="$dracutbasedir/src/skipcpio/skipcpio" | |
98fd0693 HH |
299 | else |
300 | SKIP="$dracutbasedir/skipcpio" | |
301 | fi | |
b208aad5 HH |
302 | if ! [[ -x $SKIP ]]; then |
303 | echo | |
304 | echo "'$SKIP' not found, cannot display remaining contents!" >&2 | |
305 | echo | |
306 | exit 0 | |
307 | fi | |
308 | fi | |
309 | ;; | |
310 | esac | |
311 | ||
9a52c3fd | 312 | if [[ $SKIP ]]; then |
0ce54e80 | 313 | bin="$($SKIP "$image" | { read -r -N 6 bin && echo "$bin"; })" |
3ce14286 | 314 | else |
0ce54e80 | 315 | read -r -N 6 bin < "$image" |
3ce14286 HD |
316 | fi |
317 | case $bin in | |
318 | $'\x1f\x8b'*) | |
319 | CAT="zcat --" | |
320 | ;; | |
321 | BZh*) | |
322 | CAT="bzcat --" | |
323 | ;; | |
9a52c3fd | 324 | $'\x71\xc7'* | 070701) |
18a5011f | 325 | CAT="cat --" |
3ce14286 HD |
326 | ;; |
327 | $'\x02\x21'*) | |
328 | CAT="lz4 -d -c" | |
329 | ;; | |
330 | $'\x89'LZO$'\0'*) | |
331 | CAT="lzop -d -c" | |
332 | ;; | |
ebfd53e1 | 333 | $'\x28\xB5\x2F\xFD'*) |
7dbadcc7 TPG |
334 | CAT="zstd -d -c" |
335 | ;; | |
3ce14286 | 336 | *) |
9a52c3fd | 337 | if echo "test" | xz | xzcat --single-stream > /dev/null 2>&1; then |
3ce14286 | 338 | CAT="xzcat --single-stream --" |
fd9f9024 | 339 | else |
3ce14286 HD |
340 | CAT="xzcat --" |
341 | fi | |
342 | ;; | |
343 | esac | |
66fe35eb | 344 | |
9a52c3fd | 345 | skipcpio() { |
b208aad5 HH |
346 | $SKIP "$@" | $ORIG_CAT |
347 | } | |
348 | ||
349 | if [[ $SKIP ]]; then | |
350 | ORIG_CAT="$CAT" | |
351 | CAT=skipcpio | |
352 | fi | |
353 | ||
9a52c3fd | 354 | if ((${#filenames[@]} > 1)); then |
cbf32008 | 355 | TMPFILE="$TMPDIR/initrd.cpio" |
0ce54e80 | 356 | $CAT "$image" 2> /dev/null > "$TMPFILE" |
9a52c3fd | 357 | pre_decompress() { |
0ce54e80 | 358 | cat "$TMPFILE" |
986b12d3 KS |
359 | } |
360 | CAT=pre_decompress | |
361 | fi | |
362 | ||
884e1cda HH |
363 | ret=0 |
364 | ||
75d758e8 | 365 | if [[ -n $unpack ]]; then |
97bbba69 | 366 | unpack_files |
9a52c3fd | 367 | elif ((${#filenames[@]} > 0)); then |
b208aad5 | 368 | extract_files |
3ea5d2e2 | 369 | else |
0ce54e80 | 370 | # shellcheck disable=SC2046 |
d3be9275 | 371 | version=$($CAT "$image" | cpio --extract --verbose --quiet --to-stdout -- \ |
9a52c3fd HH |
372 | $(dracutlibdirs 'dracut-*') 2> /dev/null) |
373 | ((ret += $?)) | |
ae01bd18 | 374 | echo "Version: $version" |
b208aad5 | 375 | echo |
05d2a145 HB |
376 | if [ "$modules" -eq 1 ]; then |
377 | list_modules | |
378 | echo "========================================================================" | |
379 | else | |
380 | echo -n "Arguments: " | |
0ce54e80 | 381 | # shellcheck disable=SC2046 |
d3be9275 | 382 | $CAT "$image" | cpio --extract --verbose --quiet --to-stdout -- \ |
9a52c3fd | 383 | $(dracutlibdirs build-parameter.txt) 2> /dev/null |
05d2a145 HB |
384 | echo |
385 | list_modules | |
386 | list_files | |
1ff306a3 | 387 | list_squash_content |
05d2a145 | 388 | fi |
3ea5d2e2 | 389 | fi |
4460416a | 390 | |
0ce54e80 | 391 | exit "$ret" |