]>
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" | |
134 | elif [[ -f /boot/initramfs-${KERNEL_VERSION}.img ]]; then | |
d928724c | 135 | image="/boot/initramfs-${KERNEL_VERSION}.img" |
d6343146 AAF |
136 | elif [[ $MACHINE_ID ]] \ |
137 | && mountpoint -q /efi; then | |
49ea6c42 | 138 | image="/efi/${MACHINE_ID}/${KERNEL_VERSION}/initrd" |
d6343146 AAF |
139 | elif [[ $MACHINE_ID ]] \ |
140 | && mountpoint -q /boot/efi; then | |
49ea6c42 AAF |
141 | image="/boot/efi/${MACHINE_ID}/${KERNEL_VERSION}/initrd" |
142 | else | |
143 | image="" | |
727e68d0 | 144 | fi |
dde2db3d HH |
145 | fi |
146 | ||
7d9bb76a HH |
147 | shift |
148 | while (($# > 0)); do | |
9a52c3fd | 149 | filenames[${1#/}]=1 |
7d9bb76a HH |
150 | shift |
151 | done | |
727e68d0 | 152 | |
75d758e8 | 153 | if ! [[ -f $image ]]; then |
dde2db3d HH |
154 | { |
155 | echo "No <initramfs file> specified and the default image '$image' cannot be accessed!" | |
156 | echo | |
157 | } >&2 | |
158 | usage | |
159 | exit 1 | |
160 | fi | |
074d12c1 | 161 | |
cbf32008 | 162 | TMPDIR="$(mktemp -d -t lsinitrd.XXXXXX)" |
0ce54e80 | 163 | # shellcheck disable=SC2064 |
cbf32008 MR |
164 | trap "rm -rf '$TMPDIR'" EXIT |
165 | ||
d3be9275 AŻ |
166 | dracutlibdirs() { |
167 | for d in lib64/dracut lib/dracut usr/lib64/dracut usr/lib/dracut; do | |
168 | echo "$d/$1" | |
169 | done | |
170 | } | |
171 | ||
9a52c3fd HH |
172 | extract_files() { |
173 | ((${#filenames[@]} == 1)) && nofileinfo=1 | |
3721635b | 174 | for f in "${!filenames[@]}"; do |
b208aad5 HH |
175 | [[ $nofileinfo ]] || echo "initramfs:/$f" |
176 | [[ $nofileinfo ]] || echo "========================================================================" | |
9a52c3fd HH |
177 | $CAT "$image" 2> /dev/null | cpio --extract --verbose --quiet --to-stdout "$f" 2> /dev/null |
178 | ((ret += $?)) | |
b208aad5 HH |
179 | [[ $nofileinfo ]] || echo "========================================================================" |
180 | [[ $nofileinfo ]] || echo | |
181 | done | |
182 | } | |
183 | ||
9a52c3fd | 184 | list_modules() { |
05d2a145 | 185 | echo "dracut modules:" |
0ce54e80 | 186 | # shellcheck disable=SC2046 |
d3be9275 | 187 | $CAT "$image" | cpio --extract --verbose --quiet --to-stdout -- \ |
9a52c3fd HH |
188 | $(dracutlibdirs modules.txt) 2> /dev/null |
189 | ((ret += $?)) | |
05d2a145 HB |
190 | } |
191 | ||
9a52c3fd | 192 | list_files() { |
b208aad5 HH |
193 | echo "========================================================================" |
194 | if [ "$sorted" -eq 1 ]; then | |
9a52c3fd | 195 | $CAT "$image" 2> /dev/null | cpio --extract --verbose --quiet --list | sort -n -k5 |
b208aad5 | 196 | else |
9a52c3fd | 197 | $CAT "$image" 2> /dev/null | cpio --extract --verbose --quiet --list | sort -k9 |
b208aad5 | 198 | fi |
9a52c3fd | 199 | ((ret += $?)) |
b208aad5 HH |
200 | echo "========================================================================" |
201 | } | |
202 | ||
9a52c3fd | 203 | list_squash_content() { |
8f7c332e | 204 | SQUASH_IMG="squash-root.img" |
cbf32008 MR |
205 | SQUASH_TMPFILE="$TMPDIR/initrd.root.sqsh" |
206 | ||
9a52c3fd HH |
207 | $CAT "$image" 2> /dev/null | cpio --extract --verbose --quiet --to-stdout -- \ |
208 | $SQUASH_IMG > "$SQUASH_TMPFILE" 2> /dev/null | |
1ff306a3 KS |
209 | if [[ -s $SQUASH_TMPFILE ]]; then |
210 | echo "Squashed content ($SQUASH_IMG):" | |
211 | echo "========================================================================" | |
212 | unsquashfs -ll "$SQUASH_TMPFILE" | tail -n +4 | |
213 | echo "========================================================================" | |
214 | fi | |
215 | } | |
216 | ||
9a52c3fd HH |
217 | unpack_files() { |
218 | if ((${#filenames[@]} > 0)); then | |
f81c864e | 219 | for f in "${!filenames[@]}"; do |
9a52c3fd HH |
220 | $CAT "$image" 2> /dev/null | cpio -id --quiet $verbose $f |
221 | ((ret += $?)) | |
f81c864e KS |
222 | done |
223 | else | |
9a52c3fd HH |
224 | $CAT "$image" 2> /dev/null | cpio -id --quiet $verbose |
225 | ((ret += $?)) | |
f81c864e | 226 | fi |
97bbba69 HH |
227 | } |
228 | ||
0ce54e80 | 229 | read -r -N 2 bin < "$image" |
cbf32008 | 230 | if [ "$bin" = "MZ" ]; then |
9a52c3fd HH |
231 | command -v objcopy > /dev/null || { |
232 | echo "Need 'objcopy' to unpack an UEFI executable." | |
233 | exit 1 | |
234 | } | |
cbf32008 MR |
235 | objcopy \ |
236 | --dump-section .linux="$TMPDIR/vmlinuz" \ | |
237 | --dump-section .initrd="$TMPDIR/initrd.img" \ | |
238 | --dump-section .cmdline="$TMPDIR/cmdline.txt" \ | |
239 | --dump-section .osrel="$TMPDIR/osrel.txt" \ | |
240 | "$image" /dev/null | |
241 | uefi="$image" | |
242 | image="$TMPDIR/initrd.img" | |
243 | [ -f "$image" ] || exit 1 | |
244 | fi | |
b208aad5 | 245 | |
75d758e8 | 246 | if ((${#filenames[@]} <= 0)) && [[ -z $unpack ]] && [[ -z $unpackearly ]]; then |
32dfd416 | 247 | if [ -n "$uefi" ]; then |
cbf32008 | 248 | echo -n "initrd in UEFI: $uefi: " |
0ce54e80 | 249 | du -h "$image" | while read -r a _ || [ -n "$a" ]; do echo "$a"; done |
cbf32008 MR |
250 | if [ -f "$TMPDIR/osrel.txt" ]; then |
251 | name=$(sed -En '/^PRETTY_NAME/ s/^\w+=["'"'"']?([^"'"'"'$]*)["'"'"']?/\1/p' "$TMPDIR/osrel.txt") | |
252 | id=$(sed -En '/^ID/ s/^\w+=["'"'"']?([^"'"'"'$]*)["'"'"']?/\1/p' "$TMPDIR/osrel.txt") | |
253 | build=$(sed -En '/^BUILD_ID/ s/^\w+=["'"'"']?([^"'"'"'$]*)["'"'"']?/\1/p' "$TMPDIR/osrel.txt") | |
254 | echo "OS Release: $name (${id}-${build})" | |
255 | fi | |
256 | if [ -f "$TMPDIR/vmlinuz" ]; then | |
257 | version=$(strings -n 20 "$TMPDIR/vmlinuz" | sed -En '/[0-9]+\.[0-9]+\.[0-9]+/ { p; q 0 }') | |
258 | echo "Kernel Version: $version" | |
259 | fi | |
260 | if [ -f "$TMPDIR/cmdline.txt" ]; then | |
261 | echo "Command line:" | |
262 | sed -En 's/\s+/\n/g; s/\x00/\n/; p' "$TMPDIR/cmdline.txt" | |
263 | fi | |
264 | else | |
265 | echo -n "Image: $image: " | |
0ce54e80 | 266 | du -h "$image" | while read -r a _ || [ -n "$a" ]; do echo "$a"; done |
cbf32008 MR |
267 | fi |
268 | ||
b208aad5 HH |
269 | echo "========================================================================" |
270 | fi | |
271 | ||
0ce54e80 | 272 | read -r -N 6 bin < "$image" |
b208aad5 | 273 | case $bin in |
9a52c3fd | 274 | $'\x71\xc7'* | 070701) |
18a5011f | 275 | CAT="cat --" |
9a52c3fd | 276 | is_early=$(cpio --extract --verbose --quiet --to-stdout -- 'early_cpio' < "$image" 2> /dev/null) |
ce62465c | 277 | # Debian mkinitramfs does not create the file 'early_cpio', so let's check if firmware files exist |
9a52c3fd | 278 | [[ "$is_early" ]] || is_early=$(cpio --list --verbose --quiet --to-stdout -- 'kernel/*/microcode/*.bin' < "$image" 2> /dev/null) |
b208aad5 | 279 | if [[ "$is_early" ]]; then |
75d758e8 | 280 | if [[ -n $unpack ]]; then |
f81c864e KS |
281 | # should use --unpackearly for early CPIO |
282 | : | |
75d758e8 | 283 | elif [[ -n $unpackearly ]]; then |
97bbba69 | 284 | unpack_files |
9a52c3fd | 285 | elif ((${#filenames[@]} > 0)); then |
b208aad5 HH |
286 | extract_files |
287 | else | |
288 | echo "Early CPIO image" | |
289 | list_files | |
290 | fi | |
5eb996a9 AAF |
291 | if [[ -d "$dracutbasedir/src/skipcpio" ]]; then |
292 | SKIP="$dracutbasedir/src/skipcpio/skipcpio" | |
98fd0693 HH |
293 | else |
294 | SKIP="$dracutbasedir/skipcpio" | |
295 | fi | |
b208aad5 HH |
296 | if ! [[ -x $SKIP ]]; then |
297 | echo | |
298 | echo "'$SKIP' not found, cannot display remaining contents!" >&2 | |
299 | echo | |
300 | exit 0 | |
301 | fi | |
302 | fi | |
303 | ;; | |
304 | esac | |
305 | ||
9a52c3fd | 306 | if [[ $SKIP ]]; then |
0ce54e80 | 307 | bin="$($SKIP "$image" | { read -r -N 6 bin && echo "$bin"; })" |
3ce14286 | 308 | else |
0ce54e80 | 309 | read -r -N 6 bin < "$image" |
3ce14286 HD |
310 | fi |
311 | case $bin in | |
312 | $'\x1f\x8b'*) | |
313 | CAT="zcat --" | |
314 | ;; | |
315 | BZh*) | |
316 | CAT="bzcat --" | |
317 | ;; | |
9a52c3fd | 318 | $'\x71\xc7'* | 070701) |
18a5011f | 319 | CAT="cat --" |
3ce14286 HD |
320 | ;; |
321 | $'\x02\x21'*) | |
322 | CAT="lz4 -d -c" | |
323 | ;; | |
324 | $'\x89'LZO$'\0'*) | |
325 | CAT="lzop -d -c" | |
326 | ;; | |
ebfd53e1 | 327 | $'\x28\xB5\x2F\xFD'*) |
7dbadcc7 TPG |
328 | CAT="zstd -d -c" |
329 | ;; | |
3ce14286 | 330 | *) |
9a52c3fd | 331 | if echo "test" | xz | xzcat --single-stream > /dev/null 2>&1; then |
3ce14286 | 332 | CAT="xzcat --single-stream --" |
fd9f9024 | 333 | else |
3ce14286 HD |
334 | CAT="xzcat --" |
335 | fi | |
336 | ;; | |
337 | esac | |
66fe35eb | 338 | |
9a52c3fd | 339 | skipcpio() { |
b208aad5 HH |
340 | $SKIP "$@" | $ORIG_CAT |
341 | } | |
342 | ||
343 | if [[ $SKIP ]]; then | |
344 | ORIG_CAT="$CAT" | |
345 | CAT=skipcpio | |
346 | fi | |
347 | ||
9a52c3fd | 348 | if ((${#filenames[@]} > 1)); then |
cbf32008 | 349 | TMPFILE="$TMPDIR/initrd.cpio" |
0ce54e80 | 350 | $CAT "$image" 2> /dev/null > "$TMPFILE" |
9a52c3fd | 351 | pre_decompress() { |
0ce54e80 | 352 | cat "$TMPFILE" |
986b12d3 KS |
353 | } |
354 | CAT=pre_decompress | |
355 | fi | |
356 | ||
884e1cda HH |
357 | ret=0 |
358 | ||
75d758e8 | 359 | if [[ -n $unpack ]]; then |
97bbba69 | 360 | unpack_files |
9a52c3fd | 361 | elif ((${#filenames[@]} > 0)); then |
b208aad5 | 362 | extract_files |
3ea5d2e2 | 363 | else |
0ce54e80 | 364 | # shellcheck disable=SC2046 |
d3be9275 | 365 | version=$($CAT "$image" | cpio --extract --verbose --quiet --to-stdout -- \ |
9a52c3fd HH |
366 | $(dracutlibdirs 'dracut-*') 2> /dev/null) |
367 | ((ret += $?)) | |
ae01bd18 | 368 | echo "Version: $version" |
b208aad5 | 369 | echo |
05d2a145 HB |
370 | if [ "$modules" -eq 1 ]; then |
371 | list_modules | |
372 | echo "========================================================================" | |
373 | else | |
374 | echo -n "Arguments: " | |
0ce54e80 | 375 | # shellcheck disable=SC2046 |
d3be9275 | 376 | $CAT "$image" | cpio --extract --verbose --quiet --to-stdout -- \ |
9a52c3fd | 377 | $(dracutlibdirs build-parameter.txt) 2> /dev/null |
05d2a145 HB |
378 | echo |
379 | list_modules | |
380 | list_files | |
1ff306a3 | 381 | list_squash_content |
05d2a145 | 382 | fi |
3ea5d2e2 | 383 | fi |
4460416a | 384 | |
0ce54e80 | 385 | exit "$ret" |