Saya menggunakan debian live-build untuk bekerja pada sistem yang dapat di-boot. Pada akhir proses saya mendapatkan file-file khas yang digunakan untuk mem-boot sistem langsung: file squashfs, beberapa modul GRUB dan file konfigurasi, dan file initrd.img.
Saya bisa boot dengan baik menggunakan file-file itu, meneruskan initrd ke kernel melalui
initrd=/path/to/my/initrd.img
pada baris perintah bootloader. Tetapi ketika saya mencoba memeriksa isi gambar initrd saya, seperti:
$file initrd.img
initrd.img: ASCII cpio archive (SVR4 with no CRC)
$mkdir initTree && cd initTree
$cpio -idv < ../initrd.img
pohon file yang saya dapat terlihat seperti ini:
$tree --charset=ASCII
.
`-- kernel
`-- x86
`-- microcode
`-- GenuineIntel.bin
Di mana pohon sistem file aktual, dengan tipikal / bin, / etc, / sbin ... berisi file aktual yang digunakan saat boot?
Jawaban:
Metode lewati blok cpio yang diberikan tidak berfungsi dengan baik. Itu karena gambar initrd yang saya peroleh sendiri tidak memiliki kedua arsip yang disatukan pada batas 512 byte.
Sebaliknya, lakukan ini:
Gunakan nomor terakhir (21136) yang tidak pada batas 512 byte untuk saya:
sumber
cd
ke direktori di mana Anda diekstrak arsip cpio Anda, runfind | cpio -H newc -o > /tmp/my_archive.cpio
, kemudian gzip dengangzip /tmp/my_archive.cpio
dan akhirnya, menggabungkan dengan dengan gambar microcode, jika Anda memiliki satu:cat my_microcode_image.cpio /tmp/my_archive.cpio.gz > mynewinitrd.img
. Jika Anda tidak memiliki gambar mikrokode, maka Anda bisa menggunakan file gzipped seperti di bootloader Andacpio -i
, alih-alihcpio -tdv | head
.Jika Anda tahu bahwa Anda
initrd.img
terdiri dari arsip cpio terkompresi diikuti oleh arsip cpio terkompresi gz, Anda dapat menggunakan yang berikut ini untuk mengekstrak semua file (dari kedua arsip) ke direktori kerja Anda saat ini (diuji dalam bash):Baris perintah di atas meneruskan isi
initrd.img
sebagai input standar ke dalam subkulit yang mengeksekusi dua perintahcpio -id
danzcat | cpio -id
secara berurutan. Perintah pertama (cpio -id
) berakhir setelah ia membaca semua data milik arsip cpio pertama. Konten yang tersisa kemudian diteruskan kezcat | cpio -id
, yang mendekompresi dan membongkar arsip kedua.sumber
Ternyata initrd yang dihasilkan oleh live-build Debian (dan yang mengejutkan saya, diterima oleh kernel) sebenarnya adalah gabungan dari dua gambar:
Setelah mengekstrak initrd.img asli, langsung dari output live-build, saya mendapatkan output ini:
Yang berarti bahwa ekstraksi cpio berakhir setelah parsing 896 blok masing-masing 512 Bytes. Tetapi initrd.img asli jauh lebih besar dari 896 * 512 = 458752B = 448 KB:
Jadi gambar initrd aktual yang saya cari ditambahkan tepat setelah arsip cpio pertama (yang berisi pembaruan mikrokode) dan dapat diakses menggunakan dd:
sumber
Anda dapat menggunakan
unmkinitramfs
dari initramfs-tools> = 0.126, yang disertakan sejak Debian 9 (stretch) dan Ubuntu 18.04 (bionic).sumber
Berdasarkan ide yang diberikan dalam jawaban @ woolpool, saya menulis fungsi rekursif yang akan bekerja untuk arsip cpio apa pun terlepas dari pengaturan data gabungan dan tidak memerlukan alat khusus seperti binwalk. Misalnya mkinitramfs saya menghasilkan file cpio; cpio; gzip. Ini bekerja dengan mengekstraksi setiap bagian dari file initrd bersambung, menyimpan sisanya ke tempfile dan kemudian menggunakan program "file" untuk memutuskan apa yang harus dilakukan dengan bagian selanjutnya.
Untuk menggunakan ketik: uncpio initrdfilename
sumber
Jika Anda perlu sering melakukan tugas ini, Anda mungkin ingin membuat fungsi bash kecil seperti berikut (dan mungkin menambahkannya ke .bashrc Anda):
Kode ini didasarkan pada jawaban Marc, tetapi secara signifikan lebih cepat karena binwalk hanya akan mencari file gzip. Anda dapat memintanya, seperti ini:
Anda perlu
binwalk
diinstal untuk membuatnya bekerja.sumber