BIOS用にCONFIG_X86_RESERVE_LOWメモリを予約するカーネルのポイントは何ですか?

BIOS用にCONFIG_X86_RESERVE_LOWメモリを予約するカーネルのポイントは何ですか?

少なくとも2.6カーネルから、Kconfigは「BIOS用に予約されている低メモリ量(KB)」として説明されているCONFIG_X86_RESERVE_LOWオプションを提供します。 (私が知っているのは、物理アドレス0から始めて4Kから640Kまでの範囲です。)

システムから起動すると、ログは起動プロセスを開始しようとしたときに通知されます。

BIOS-provided physical RAM map:
BIOS-e820: [mem 0x0000000000000000-0x000000000009ebff] usable

これから、私はBIOSがRAMの最初の0x9ec00(〜640K)バイトを使用できることをカーネルに知らせていると推測します。 (保存されていません)

数行をさらに見ると、次の内容を読むことができます。

e820: update [mem 0x00000000-0x00000fff] usable ==> reserved

私の設定の結果であることがわかります。 CONFIG_X86_RESERVE_LOW = 4K

しかし、BIOS自体が0〜0x9ebffの範囲を使用できると主張している場合、カーネルがBIOSのために<〜640Kの少ないメモリを「予約」することは何ですか?

答え1

この設定オプションの長いヘルプテキストが表示されます。 2つの理由を提供します。

config X86_RESERVE_LOW
int "BIOS用に予約されたメモリ量が少ない(KB)"
デフォルト値64
範囲4 640
ヘルプ

BIOS用に予約されているメモリの少量を指定します。

最初のページにはカーネルで使用してはならないBIOSデータ構造が含まれているため、このページは常に予約する必要があります。

[切る]

オンラインでも同様のコメントがあります。パスワード:

     * A special case is the first 4Kb of memory;
     * This is a BIOS owned area, not kernel ram, but generally
     * not listed as such in the E820 table.

レガシーBIOSは最初の1280バイト(0x500)を使用します。 LinuxはMMUページサイズ(4096バイト)単位でRAMを割り当てます。 オペレーティングシステムの開発指摘 -

すべてのBIOS機能が呼び出され、カーネルがメモリのどこかにロードされた後、ブートローダまたはカーネルはリアルモードを永久に終了することができます(通常32ビット保護モード)。カーネルがリアルモードを使用しなくなった場合は、PCメモリの最初の0x500バイトを再利用して上書きすることができます。

Linuxは通常BIOSを呼び出すことはできません。しかし、あまりにも早く起動し、終了し、スリープモードから再起動するなど、怖い瞬間にそれを行うことができます。 UEFIを使用してシステムを起動する場合、Linuxが認識するBIOSはありません。

また、最初のページを保持することは、成功した物理メモリ割り当てが決して値0を返さないことを意味します。 Cプログラミングでは、伝統的に"NULLポインタ"を示すためにアドレス0を予約します。私たちはこれが反映されていることを見ることができますmemblock_phys_alloc_range()。この時点で変更することは成功しそうではありません(そして危険です:-)。

 * Return: physical address of the allocated memory block on success,
 * %0 on failure.
 */
phys_addr_t __init memblock_phys_alloc_range(

これが2番目の理由です。

デフォルトでは、物理RAMの最初の64Kを予約します。多くのBIOSが一時停止/再開またはモニターケーブルの挿入などのイベント中にこのメモリ範囲を破損することが知られているため、カーネルはそれを使用しないでください。

BIOSがすべてのメモリを予約し、正しく使用できると確信している場合は、4に設定できます。 BIOSがデフォルトの64K領域の外側に問題があることがわかっている場合は、これを640に設定して、低いメモリ範囲全体を使用しないようにすることができます。

BIOSに問題がある場合(たとえば、一時停止/再開が機能しない、または特定のハードウェアホットプラグイベントの後にカーネルパニックなど)、X86_CHECK_BIOS_CORRUPTION = yを有効にして、カーネルが一般的な破損パターンを確認できるようにすることができます。

不明な場合は、この値をデフォルト値の64のままにしてください。

最も安全な仮定は、これがBIOSと同様にUEFIファームウェアにも当てはまるということです:-).

v3.9以降、カーネルログメッセージに非常に低い保存期間は表示されません。それも表示されません/proc/iomem。カーネルは予約済みの最初の4kのみを表示しますが、残りのメモリはまだ予約されている必要があります。 e820マップには追加されていないだけです。別のリストに追加されます。この変更に対するパッチは次のとおりです。x86、mm:低いメモリを保存するために、後で初期化を進めます。

追加の保留とそれを求める悲しい物語についてもっと知りたい場合は、次のパッチの投稿をご覧ください。

x86:リカバリ中にアドレス0xc000を破損するDMIの問題をAMI BIOSに追加しました。

Alan JenkinsとAndy Wettsteinは、一時停止/再開のメモリ破損のバグを報告しました。これについての詳細は、ここで説明されています。

http://bugzilla.kernel.org/show_bug.cgi?id=11237

バグは、BIOSがe820に予約されたものとして登録されていないか、カーネルにこれを知らせずに物理アドレス0xc000のメモリ1Kを上書きしたことです。

AMI BIOSenを検出し、対応する1Kを維持します。

このバグは見つけるのが非常に難しく、数週間と多くのデバッグとパッチ操作が必要なため、非常に広範なブラシ(すべてのAMI BIOSシステムで1K予約)を適用します。

このバグはCONFIG_X86_CHECK_BIOS_CORRUPTION = yデバッグ機能で発見されました。この機能は、同様のバグが疑われる場合は、他のシステムでも有効にすることで、メモリ不足で破損したメモリを検索することができます。

x86: X86_RESERVE_LOW_64Kを追加

このバグジラ:

http://bugzilla.kernel.org/show_bug.cgi?id=11237

一時停止/再開およびその他のハードウェアイベント中に、BIOSは物理メモリの最初の64Kを使用するさまざまなシステムを文書化しました。

現在、私たちはすべてのAMIとPhoenix BIOSシステムでこのメモリを予約しています。このような微妙なメモリ破損の問題を追求するには、人生が短すぎるため、基本的に頑丈に努めています。

ただし、この設定を上書きできます。最初の64Kのメモリをカーネルに使用したいユーザーは、CONFIG_X86_RESERVE_LOW_64K = nを介してこの機能を無効にできます。

x86、BIOS:デフォルトでは、すべてのBIOSは下位64Kを予約しています。

低い64Kを維持する必要があるBIOSのリストがますます長くなっているので、これをすべてのBIOSのデフォルト値に設定してください。これにより、コードを簡素化し、最初の4K予約コードと統合することができます。

これはカーネルバグジラ16661を修正し、他のものは誰が知っていますか?

バグ 16661 - 低メモリ破損

[...]これは、私たちが彼のBIOS(dmidecode情報を提供する)をarch / x86 / kernel / setup.cのブラックリストbad_bios_dmi_tableに追加する必要があることを意味します。しかし、結論は64Kは少量のメモリであり、リストには多数の既存のBIOSが含まれているため、無条件に残す必要があるということです。

私が知る限り、Windows 7は実際にBIOSエラーを防ぐために1MiB未満のすべてのメモリを予約しています。

関連情報