私はdebian live-buildを使って起動可能なシステムで作業しています。プロセスの終わりに、ライブシステムを起動するための一般的なファイルである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...)はどこにありますか?
答え1
与えられたcpioブロックをスキップする方法は安定して動作しません。これは、私が直接取得したinitrdイメージが512バイトの境界で2つのアーカイブをリンクしていないためです。
代わりに、以下を実行してください。
apt-get install binwalk
legolas [mc]# binwalk initrd.img
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 ASCII cpio archive (SVR4 with no CRC), file name: "kernel", file name length: "0x00000007", file size: "0x00000000"
120 0x78 ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86", file name length: "0x0000000B", file size: "0x00000000"
244 0xF4 ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode", file name length: "0x00000015", file size: "0x00000000"
376 0x178 ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode/GenuineIntel.bin", file name length: "0x00000026", file size: "0x00005000"
21004 0x520C ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
21136 0x5290 gzip compressed data, from Unix, last modified: Sat Feb 28 09:46:24 2015
最後の数字(21136)を使用すると、512バイトの境界にはありません。
legolas [mc]# dd if=initrd.img bs=21136 skip=1 | gunzip | cpio -tdv | head
drwxr-xr-x 1 root root 0 Feb 28 09:46 .
drwxr-xr-x 1 root root 0 Feb 28 09:46 bin
-rwxr-xr-x 1 root root 554424 Dec 17 2011 bin/busybox
lrwxrwxrwx 1 root root 7 Feb 28 09:46 bin/sh -> busybox
-rwxr-xr-x 1 root root 111288 Sep 23 2011 bin/loadkeys
-rwxr-xr-x 1 root root 2800 Aug 19 2013 bin/cat
-rwxr-xr-x 1 root root 856 Aug 19 2013 bin/chroot
-rwxr-xr-x 1 root root 5224 Aug 19 2013 bin/cpio
-rwxr-xr-x 1 root root 3936 Aug 19 2013 bin/dd
-rwxr-xr-x 1 root root 984 Aug 19 2013 bin/dmesg
答え2
ファイルが圧縮されていないcpioアーカイブとgzで圧縮されたcpioアーカイブで構成されていることがわかっている場合は、次のコマンドを使用して両方のアーカイブのすべてのファイルを現在のinitrd.img
作業ディレクトリ(bashでテスト)に抽出できます。
(cpio -id; zcat | cpio -id) < /path/to/initrd.img
上記のコマンドラインは、そのinitrd.img
内容を標準入力としてサブシェルに渡し、サブシェルは両方のcpio -id
コマンドを順番に実行しますzcat | cpio -id
。最初のコマンド(cpio -id
)は、最初のcpioアーカイブに属するすべてのデータを読み取り、終了します。その後、残りのコンテンツがに転送され、zcat | cpio -id
2番目のアーカイブが解凍されます。
答え3
Debianのライブビルド(驚くべきことにカーネルで許可されています)によって作成されたinitrdは、実際に2つの画像をリンクしていることがわかりました。
- プロセッサに適用されるマイクロコードアップデートを含むCPIOアーカイブ。
- 実際、initrdファイルツリー(および予想される/ etc / bin / sbin / dev ...ディレクトリ)を含むgzipで圧縮されたcpioアーカイブです。
ライブビルド出力から直接オリジナルinitrd.imgを抽出した後、次のような出力が得られました。
$cpio -idv ../initrd.img
kernel
kernel/x86
kernel/x86/microcode
kernel/x86/microcode/GenuineIntel.bin
896 blocks
これは、896ブロック(それぞれ512バイト)を解析した後、cpio抽出が終了することを意味します。ただし、元のinitrd.imgは896 * 512 = 458752B = 448KBよりはるかに大きいです。
$ls -liah initrd.img
3933924 -r--r--r-- 1 root root 21M Oct 21 10:05 initrd.img
したがって、私が探している実際のinitrdイメージは、最初のcpioアーカイブ(マイクロコードアップデートを含むアーカイブ)の後ろに添付され、ddを使用してアクセスできます。
$dd if=initrd.img of=myActualInitrdImage.img.gz bs=512 skip=896
答え4
@woolpoolの回答で提供されているアイデアに従って、接続データの配列に関係なく、すべてのcpioアーカイブで動作し、特別なツール(binwalkなど)を必要としない再帰関数を作成しました。たとえば、私のmkinitramfsはcpio;cpio;gzipファイルを生成しています。リンクされたinitrdファイルの各部分を抽出し、残りの部分を一時ファイルに保存してから、Fileプログラムを使用して次の部分に何をするかを決定する方法で動作します。
uncpio(){
if [[ $(wc -c $1 | cut -d ' ' -f1) -eq 0 ]]; then
return
fi
type=$(cat $1 | file -)
local tmpfile=$(date +%s.%N)
echo -e "\n$type"
if [[ $type =~ .*cpio.* ]]; then
cat $1 | (cpio -id; cat >$tmpfile)
elif [[ $type =~ .*gzip.* ]]; then
zcat $1 | (cpio -id; cat >$tmpfile)
else
return
fi
uncpio $tmpfile
rm $tmpfile
}
使用タイプ:uncpio初期化ファイル名