Estou usando o debian live-build para trabalhar em um sistema inicializável. No final do processo, recebo os arquivos típicos usados para inicializar um sistema ativo: um arquivo squashfs, alguns módulos GRUB e arquivos de configuração e um arquivo initrd.img.
Eu posso inicializar muito bem usando esses arquivos, passando o initrd para o kernel via
initrd=/path/to/my/initrd.img
na linha de comando do carregador de inicialização. Mas quando tento examinar o conteúdo da minha imagem initrd, é assim:
$file initrd.img
initrd.img: ASCII cpio archive (SVR4 with no CRC)
$mkdir initTree && cd initTree
$cpio -idv < ../initrd.img
a árvore de arquivos que recebo fica assim:
$tree --charset=ASCII
.
`-- kernel
`-- x86
`-- microcode
`-- GenuineIntel.bin
Onde está a árvore do sistema de arquivos real, com o típico / bin, / etc, / sbin ... contendo os arquivos reais usados durante a inicialização?
Respostas:
O método cpio block skip fornecido não funciona de maneira confiável. Isso porque as imagens initrd que eu estava obtendo não tinham os dois arquivos concatenados em um limite de 512 bytes.
Em vez disso, faça o seguinte:
Use o último número (21136) que não está em um limite de 512 bytes para mim:
fonte
cd
para o diretório onde você extraiu o arquivo cpio, runfind | cpio -H newc -o > /tmp/my_archive.cpio
, então gzip-lo comgzip /tmp/my_archive.cpio
e, finalmente, concatenar-lo com a com a imagem microcódigo, se você tivesse um:cat my_microcode_image.cpio /tmp/my_archive.cpio.gz > mynewinitrd.img
. Se você não tem uma imagem de microcódigo, então você pode apenas usá-lo compactado arquivo como está na sua bootloadercpio -i
, em vez decpio -tdv | head
.Se você sabe que
initrd.img
consiste em um arquivo cpio descompactado seguido por um arquivo cpio compactado com gz, você pode usar o seguinte para extrair todos os arquivos (de ambos os arquivos) para o diretório de trabalho atual (testado no bash):A linha de comando acima passa o conteúdo
initrd.img
como entrada padrão para um subshell que executa os dois comandoscpio -id
ezcat | cpio -id
sequencialmente. O primeiro comando (cpio -id
) termina depois de ler todos os dados pertencentes ao primeiro arquivo cpio. O conteúdo restante é passado parazcat | cpio -id
, que descompacta e descompacta o segundo arquivo morto.fonte
Acontece que o initrd gerado pelo live-build do Debian (e para minha surpresa, aceito pelo kernel) é na verdade a concatenação de duas imagens:
Ao extrair o initrd.img original, direto da saída do live-build, obtive esta saída:
O que significa que a extração do cpio terminou após analisar 896 blocos de 512 bytes cada. Mas o initrd.img original era muito maior que 896 * 512 = 458752B = 448 KB:
Portanto, a imagem initrd que eu estava procurando foi anexada logo após o primeiro arquivo cpio (aquele que contém as atualizações de microcódigo) e pode ser acessada usando o dd:
fonte
Você pode usar
unmkinitramfs
initramfs-tools> = 0.126, que está incluído desde o Debian 9 (stretch) e Ubuntu 18.04 (biônico).fonte
Com base na idéia dada na resposta do @ woolpool, escrevi uma função recursiva que funcionará para qualquer arquivo cpio, independentemente da organização dos dados concatenados, e não requer ferramentas especiais como o binwalk. Por exemplo, meu mkinitramfs estava produzindo um arquivo cpio; cpio; gzip. Ele funciona extraindo cada parte do arquivo initrd concatenado, salvando o restante em um arquivo temporário e, em seguida, usando o programa "arquivo" para decidir o que fazer com a próxima parte.
Para usar o tipo: uncpio initrdfilename
fonte
Se você precisar executar essa tarefa com frequência, convém criar uma pequena função bash como a seguinte (e talvez adicioná-la ao seu .bashrc):
O código é baseado na resposta de Marc, mas é significativamente mais rápido, pois o binwalk procurará apenas arquivos gzip. Você pode invocá-lo, assim:
Você precisará
binwalk
instalado para fazê-lo funcionar.fonte