Estoy usando debian live-build para trabajar en un sistema de arranque. Al final del proceso obtengo los archivos típicos utilizados para arrancar un sistema en vivo: un archivo squashfs, algunos módulos GRUB y archivos de configuración, y un archivo initrd.img.
Puedo arrancar bien usando esos archivos, pasando el initrd al kernel a través de
initrd=/path/to/my/initrd.img
en la línea de comando del gestor de arranque. Pero cuando trato de examinar el contenido de mi imagen initrd, así:
$file initrd.img
initrd.img: ASCII cpio archive (SVR4 with no CRC)
$mkdir initTree && cd initTree
$cpio -idv < ../initrd.img
el árbol de archivos que obtengo se ve así:
$tree --charset=ASCII
.
`-- kernel
`-- x86
`-- microcode
`-- GenuineIntel.bin
¿Dónde está el árbol del sistema de archivos real, con el típico / bin, / etc, / sbin ... que contiene los archivos reales utilizados durante el arranque?
Respuestas:
El método de omisión de bloque cpio dado no funciona de manera confiable. Esto se debe a que las imágenes de initrd que estaba obteniendo no tenían ambos archivos concatenados en un límite de 512 bytes.
En cambio, haz esto:
Use el último número (21136) que no está en un límite de 512 bytes para mí:
fuente
cd
en el directorio en el que extrajo el archivo cpio, carrerafind | cpio -H newc -o > /tmp/my_archive.cpio
, entonces gzip congzip /tmp/my_archive.cpio
y, finalmente, concatenar con la imagen de microcódigo con, si tuviera uno:cat my_microcode_image.cpio /tmp/my_archive.cpio.gz > mynewinitrd.img
. Si no tenía una imagen de microcódigo, puede usar su archivo comprimido tal como está en su gestor de arranquecpio -i
, en lugar decpio -tdv | head
.Si sabe que su
initrd.img
archivo consta de un archivo cpio sin comprimir seguido de un archivo cpio comprimido con gz, puede usar lo siguiente para extraer todos los archivos (de ambos archivos) en su directorio de trabajo actual (probado en bash):La línea de comandos anterior pasa el contenido de
initrd.img
como entrada estándar a una subshell que ejecuta los dos comandoscpio -id
y de formazcat | cpio -id
secuencial. El primer comando (cpio -id
) termina una vez que ha leído todos los datos que pertenecen al primer archivo cpio. El contenido restante se pasa azcat | cpio -id
, que descomprime y desempaqueta el segundo archivo.fuente
Resulta que el initrd generado por la construcción en vivo de Debian (y para mi sorpresa, aceptado por el núcleo) es en realidad la concatenación de dos imágenes:
Al extraer el initrd.img original, directamente de la salida de construcción en vivo, obtuve esta salida:
Lo que significa que la extracción de cpio terminó después de analizar 896 bloques de 512 bytes cada uno. Pero el initrd.img original era mucho más grande que 896 * 512 = 458752B = 448 KB:
Entonces, la imagen de initrd real que estaba buscando se agregó justo después del primer archivo cpio (el que contiene las actualizaciones de microcódigo) y se podía acceder a ella usando dd:
fuente
Puede usar
unmkinitramfs
desde initramfs-tools> = 0.126, que se incluye desde Debian 9 (stretch) y Ubuntu 18.04 (bionic).fuente
Basado en la idea dada en la respuesta de @ woolpool, escribí una función recursiva que funcionará para cualquier archivo cpio independientemente de la disposición de los datos concatenados y no requiere herramientas especiales como binwalk. Por ejemplo, mi mkinitramfs estaba produciendo un archivo cpio; cpio; gzip. Funciona al extraer cada parte del archivo initrd concatenado, guardar el resto en un archivo temporal y luego usar el programa "archivo" para decidir qué hacer con la siguiente parte.
Para usar el tipo: uncpio initrdfilename
fuente
Si necesita realizar esta tarea con frecuencia, es posible que desee crear una pequeña función bash como la siguiente (y tal vez agregarla a su .bashrc):
El código se basa en la respuesta de Marc, pero es significativamente más rápido ya que binwalk solo buscará archivos gzip. Puedes invocarlo así:
Deberá
binwalk
instalarlo para que funcione.fuente