Я использую live-сборку Debian для работы на загрузочной системе. К концу процесса я получаю типичные файлы, используемые для загрузки работающей системы: файл squashfs, некоторые модули GRUB и файлы конфигурации, а также файл initrd.img.
Я могу нормально загружаться, используя эти файлы, передавая initrd ядру через
initrd=/path/to/my/initrd.img
в командной строке загрузчика. Но когда я пытаюсь проверить содержимое моего образа initrd, вот так:
$file initrd.img
initrd.img: ASCII cpio archive (SVR4 with no CRC)
$mkdir initTree && cd initTree
$cpio -idv < ../initrd.img
дерево файлов, которое я получаю, выглядит так:
$tree --charset=ASCII
.
`-- kernel
`-- x86
`-- microcode
`-- GenuineIntel.bin
Где находится фактическое дерево файловой системы, с типичными / bin, / etc, / sbin ..., содержащими фактические файлы, используемые во время загрузки?
Ответы:
Данный метод пропуска блока cpio не работает надежно. Это потому, что образы initrd, которые я получал сам, не объединяли оба архива на границе 512 байт.
Вместо этого сделайте это:
Используйте последнее число (21136), которое не находится на границе 512 байт для меня:
источник
cd
в директорию , куда вы распаковали свой архив CPIO, бегfind | cpio -H newc -o > /tmp/my_archive.cpio
, затем GZIP егоgzip /tmp/my_archive.cpio
и , наконец, сцепить его с с микрокода изображением, если у вас один:cat my_microcode_image.cpio /tmp/my_archive.cpio.gz > mynewinitrd.img
. Если у вас не было изображения микрокода, то вы можете просто использовать файл gzip, который есть в вашем загрузчикеcpio -i
вместоcpio -tdv | head
.Если вы знаете, что вы
initrd.img
состоите из несжатого архива cpio, за которым следует gp-сжатый архив cpio, вы можете использовать следующее для извлечения всех файлов (из обоих архивов) в текущий рабочий каталог (протестировано в bash):Приведенная выше командная строка передает содержимое
initrd.img
стандартного ввода в подоболочку, которая выполняет две командыcpio -id
иzcat | cpio -id
последовательно. Первая команда (cpio -id
) завершается, как только она прочитает все данные, принадлежащие первому архиву cpio. Оставшийся контент затем передаетсяzcat | cpio -id
, который распаковывает и распаковывает второй архив.источник
Оказывается, initrd, сгенерированный live-сборкой Debian (и, к моему удивлению, принятый ядром), на самом деле является объединением двух образов:
После извлечения исходного initrd.img прямо из вывода live-build я получил следующий вывод:
Это означает, что извлечение cpio закончилось после анализа 896 блоков по 512 байт каждый. Но исходный файл initrd.img был больше, чем 896 * 512 = 458752B = 448 КБ:
Таким образом, фактическое изображение initrd, которое я искал, было добавлено сразу после первого архива cpio (содержащего обновления микрокода), и к нему можно было получить доступ с помощью dd:
источник
Вы можете использовать
unmkinitramfs
из initramfs-tools> = 0.126, который входит в состав Debian 9 (stretch) и Ubuntu 18.04 (bionic).источник
Основываясь на идее, приведенной в ответе @ woolpool, я написал рекурсивную функцию, которая будет работать для любого архива cpio независимо от расположения объединенных данных и не требует специальных инструментов, таких как binwalk. Например, мой mkinitramfs создавал файл cpio; cpio; gzip. Он работает, извлекая каждую часть объединенного файла initrd, сохраняя оставшуюся часть в временный файл и затем используя программу «file», чтобы решить, что делать со следующей частью.
Чтобы использовать тип: uncpio initrdfilename
источник
Если вам нужно часто выполнять эту задачу, вы можете создать небольшую функцию bash, подобную следующей (и, возможно, добавить ее в ваш .bashrc):
Код основан на ответе Марка, но он значительно быстрее, так как binwalk будет искать только файлы gzip. Вы можете вызвать это, как это:
Вам нужно будет
binwalk
установить, чтобы он работал.источник