いくつかの部分で構成される複合ファイルを分解しようとしています。そのうちの1つは、他のいくつかのファイルに挟まれた非圧縮カーネルです。難しいことがわかっているカーネル部分の正確な長さを見つけようとしています。
vmlinuxヘッダーに、ブートローダーが実行前に読み取ることになっているデータの量を示すものがありますか、それともvmlinuxファイルのすべてのコンテンツがブートローダーからのハンドオフ時にロードされると想定されていますか?
承認された回答:
簡単な答えは「いいえ」ですが、これがELFイメージの場合は、ハッキングを行うことでカーネルを見つけることができます。 readelf
を参照してください 以下をハックしてください。
ブートローダーは、カーネルとルートファイルシステムが存在するファイルの形式を知る責任があります。これには、どのような形式であっても、カーネルファイルのサイズを知ることが含まれます。 PowePCとBlackfinでは、ブートローダーは、カーネルが圧縮されている場合はカーネル全体を解凍し、RAMの最終的な場所に書き込む役割を果たします。 ARMでは、カーネルは自己解凍型である可能性があり、ブートローダーは生のカーネルファイルをRAM内の便利な場所にコピーして、実行を開始するだけで済みます。
カーネルが自己解凍している場合、圧縮されたカーネルファイルのサイズを示す記号は、使用されている解凍アルゴリズムに応じて、ファイルの先頭の解凍コードのどこかにある場合とない場合がありますが、特定のカーネルビルドのリンカーマップがない場所を知る。確かに、ブートローダーには知る方法がありません。
非圧縮のカーネルコード自体は、_stext
という2つの記号で囲まれています。 および_end
そのアドレスはカーネル自体の開始と終了ですが、initramfsがカーネルバイナリにリンクされている場合は、含まれているinitramfsの範囲は含まれません。 initramfsの範囲は、リンカーによって2つのカーネルシンボル__initramfs_start
で設定されます。 および__initramfs_end
。ブートローダーには通常、カーネルシンボルテーブルを読み取る機能がありません(System.map
にあります)。 ファイル)、この機能がないと、_end
がどこにあるかを知る方法がありません。 および__initrams_end
シンボルはカーネルファイルにあります。つまり、シンボルの位置は、バイナリファイルの先頭からの固定オフセットではありません。リンク時に決定され、カーネルビルド構成によって異なる場合があります。
ELF形式の非圧縮カーネルの場合、ELFヘッダー(177 E L F
)を探すことで、vmlinuxファイルの先頭を特定できる可能性があります。 od -c
で 複合ファイルのダンプ)。その後、readelf -e
を実行できます またはobjdump -h
この時点からのファイルの残りの部分で、ファイルオフセットが最も高いセクションを見つけます(.shstrtab
)。このオフセットにセクションサイズを追加すると、vmlinuxが終了します。ストリップされていないPPCvmlinuxを使用してこのメソッドをテストし、スタンドアロンのvnlinuxファイルサイズと正確に一致するサイズを取得しました。カーネルを削除した後、このメソッドは、削除された画像サイズよりも1283バイト短い結果をもたらしました。
組み込みシステムは通常、mkimage
などのファイル形式を使用します カーネル、rootfs、デバイスツリーおよびその他のコンポーネントをパックします。たとえば、U-bootはmkimageを認識しているため、カーネルバイナリがmkimageファイル内のどこで開始および終了するか、カーネルが圧縮されているかどうか、およびカーネルファイルを書き込むRAMアドレスを認識します。