
IBM PC互換コンピューティングにおいて、DOSメモリ管理とは、アプリケーションが640キビバイト(640×1024バイト)(KiB)を超える「従来型メモリ」にアクセスできるようにするために使用されるソフトウェアと技術を指します。640 KiBの制限はIBM PCおよびそれに近い互換機に固有のものでした。DOSを実行する他のマシンでは制限が異なり、たとえばApricot PCは最大768 KiB、Sirius Victor 9000は896 KiBでした。IBMファミリーのメモリ管理は、オリジナルのPC設計[ 1 ]およびリアルモードDOSとの後方互換性を維持しながら、コンピュータユーザーが大量の低コストメモリと新世代プロセッサを利用できるようにする必要があるため、複雑でした。DOSはMicrosoft WindowsやIBM PCの当初の恣意的な640 KiBの制限に縛られない他の32ビットオペレーティングシステムに取って代わられたため 、パーソナルコンピュータのメモリ管理には、ユーザーがシステムの内部設定やパラメータを手動で操作する必要はなくなりました。
640 KiBという制限は、それを回避するためのハードウェアとソフトウェアに大きな複雑さをもたらした。マシン内の物理メモリは、ベースメモリ(または従来型メモリ、下位メモリを含む)、上位メモリ、ハイメモリ(上位メモリとは異なる)、拡張メモリ、拡張メモリの組み合わせとして構成でき、それぞれ異なる方法で処理された。
初代IBM PCで使用されていたIntel 8088プロセッサは20本のアドレス線を持っていたため、1 MiB(2 20バイト)のメモリを直接アドレス指定することができました。このアドレス空間の異なる領域は、異なる用途で使用される異なる種類のメモリに割り当てられていました。アドレス空間の最下位から始めると、PCには読み書き可能なランダムアクセスメモリ(RAM)が搭載されており、これはDOSやアプリケーションプログラムによって使用されました。このメモリの最初の部分はシステムのマザーボードに搭載されていました(初期の機種では64 KiB、後に256 KiBに改訂 )。メモリは拡張スロットに差し込むカードで追加できました。各カードには、アドレス空間のどの部分がそのカード上のメモリやデバイスにアクセスするかを制御するためのストラップまたはスイッチが含まれていました。
IBM PCでは、最大640 KiBまでのアドレス空間全体がRAMとして利用可能でした。このアドレス空間は、起動時にすべてのバージョンのDOSから自動的にアクセスできるため、「従来型メモリ」と呼ばれています。従来型メモリの最初の64 KiBであるセグメント0は、低メモリ領域とも呼ばれます。通常、拡張メモリはマザーボード上のメモリとアドレス空間内で連続するように設定されます。マザーボードメモリと拡張メモリの間に未割り当てのギャップがあると、メモリはDOSによって使用可能なメモリとして自動的に検出されません。
上位メモリ領域 (UMA) は、640~1024 KiB (0xA0000~0xFFFFF)のアドレス空間を指します。0xA0000 ~0xBFFFF の 128 KiB 領域は、VGAスクリーン メモリとレガシー SMM 用に予約されていました。0xC0000 ~0xDFFFF の 128 KiB 領域は、ビデオ BIOSを含むデバイスオプション ROM用に予約されていました。0xE0000~0xEFFFF の 64 KiB 領域は、BIOSの下位 BIOS 領域として予約されていました。0xF0000~0xFFFFF の 64 KiB 領域は、BIOS の上位 BIOS 領域として予約されていました。[ 2 ]
例えば、モノクロビデオアダプタのメモリ領域は704~736 KiB(0xB0000~0xB7FFF)でした。モノクロディスプレイアダプタのみを使用する場合は、0xA0000~0xAFFFFのアドレス空間をRAMに使用でき、これは従来のメモリと連続しています。[ 3 ]
システムBIOS ROMは、CPUの開始アドレスがプロセッサの設計によって固定されているため、アドレス空間の上限付近に配置する必要があります。開始アドレスはハードウェアリセット後にCPUのプログラムカウンタにロードされ、システムへの電源供給が中断された後も保持される定義済みの値を持つ必要があります。リセット時または電源投入時に、CPUはシステムROMからアドレスをロードし、定義されたROMの場所にジャンプしてシステム起動時の自己診断テストの実行を開始し、最終的にオペレーティングシステムをロードします。
ビデオアダプタ、ハードドライブコントローラ、ネットワークアダプタなどの拡張カードは、上位メモリ領域の多くのメモリ割り当てを使用する可能性があるため、一部のカードの組み合わせの構成には、動作するカード設定とメモリマッピングを見つけるために、ドキュメントを注意深く読んだり、実験したりする必要がありました。2 つのデバイスを同じ物理メモリ アドレスを使用するようにマッピングすると、システムが停止したり不安定になったりする可能性があります。[ 3 ]通常のシステムでは、上位メモリ領域のすべてのアドレスが使用されるわけではありません。未使用の物理アドレスは、プロセッサによってアクセスされると、未定義のシステム依存のデータが返されます。
メモリ価格が下がると、表計算ソフトやコンピュータ支援製図などのアプリケーションプログラムは、システム内の物理メモリをより多く活用するように変更されました。8088および8086の仮想メモリはプロセッサハードウェアでサポートされておらず、当時のディスク技術では実用的とは言えないほど低速で扱いにくいものでした。拡張メモリは、アプリケーションプログラムがプロセッサのアドレス空間から直接見える範囲よりも多くのRAMにアクセスできるようにするシステムでした。このプロセスはバンク切り替えの一種でした。追加のRAMが必要な場合、ドライバソフトウェアは一時的に拡張メモリの一部をプロセッサからアクセス可能にし、そのメモリ内のデータが更新されると、別の部分をプロセッサのアドレス空間にスワップインすることができました。アドレスラインが20本しかないIBM PCおよびIBM PC/XTでは、おそらく1メガバイト以上の拡張メモリを搭載した専用拡張メモリカードが作られ、そのメモリを8088アドレス空間の特定の部分でプロセッサからアクセスできるようにするロジックが基板上に実装されていました。
拡張メモリの割り当てと使用は、アプリケーションプログラムからは透過的ではありませんでした。アプリケーションは、特定のデータがどの拡張メモリバンクに格納されているかを追跡する必要があり、そのデータへのアクセスが必要になったときには、(ドライバプログラムを介して)拡張メモリボードに、そのメモリ領域をプロセッサのアドレス空間にマッピングするように要求する必要がありました。アプリケーションは拡張メモリを比較的自由に使用できましたが、ドライバや常駐プログラム(TSR)などの他の多くのソフトウェアコンポーネントは、通常、640Kの「従来型メモリ」領域内に留まるように制約されており、この領域はすぐに非常に希少なリソースとなりました。
IBM PC/ATが導入された際、 Intel ファミリー プロセッサのセグメント化メモリアーキテクチャには、「リアル」モードで 1 MiB をわずかに超えるメモリをアドレス指定できるという副産物がありました。80286 は 20 を超えるアドレス ラインを持っていたため、セグメントとオフセットの特定の組み合わせによって、0x0100000 (2 20 ) の位置より上のメモリを指すことができました。80286 は最大 16 MiB のシステム メモリをアドレス指定できたため、メモリ アドレスが「ラップアラウンド」する動作がなくなりました。必要なアドレス ラインが存在するようになったため、組み合わせ F800:8000 はもはや物理アドレス 0x0000000 ではなく、正しいアドレス 0x00100000 を指すようになりました。
その結果、一部の DOS プログラムが動作しなくなりました。 PC および XT の動作との互換性を維持するために、AT にはA20 ラインゲート (ゲート A20) が搭載されており、AT のメモリ アドレスが 8088 プロセッサの場合と同様に下位メモリにラップアラウンドするようになっていました。このゲートは、当初はキーボード コントローラを介して制御でき、このために設計されたプログラムがリアル モードで追加の 65,520 バイト (64 KiB) のメモリにアクセスできるようになっていました。起動時に、BIOS はまずシステムのメモリ全体をカウントしてテストする際に A20 を有効にし、オペレーティングシステムに制御を渡す前に無効にします。 A20 ラインを有効にすることは、保護モードのx86オペレーティングシステムが起動プロセスで最初に行う手順の 1 つです。多くの場合、ブート ストラップからカーネルに制御が渡される前です (たとえば Linux の場合)。
高メモリ領域(HMA)とは、IBM PC/ATまたは互換マイクロコンピュータの拡張メモリのうち、最初の64 KiBから16バイトを除いた領域で構成されるRAM領域のことである。
当初、このロジックゲートはIntel 8042キーボードコントローラに接続されたゲートでした。その制御は比較的低速な処理でした。その後、システムメモリ全体にアクセスするプログラムとこのラップアラウンドを必要とするプログラムのマルチタスク処理をより効率的に行うための他の方法が追加されました。当初はさまざまな方法がありましたが、最終的に業界はPS/2方式を採用し、ポート92hのビットを使用してA20ラインを制御することに落ち着きました。
A20を切断しても、1MiBを超えるすべてのメモリアクセスがラップされるわけではなく、1MiB、3MiB、5MiBなどの範囲内のアクセスのみがラップされます。リアルモードソフトウェアは1MiBをわずかに超える領域のみに関心があったため、ゲートA20で十分でした。
Intel 80386で導入された仮想8086モードでは、プロセッサの仮想メモリ機能を利用してA20のラップアラウンドをシミュレートできます。物理メモリを複数の仮想アドレスにマッピングできるため、仮想メモリの最初のメガバイトにマッピングされたメモリを、仮想メモリの2番目のメガバイトに再度マッピングすることが可能です。オペレーティングシステムは、ゲートA20への変更をインターセプトし、仮想メモリのアドレス空間にそれに応じた変更を加えることができるため、ゲートA20のトグル動作の効率性は関係なくなります。
マイクロソフト製品の中で最初にHMAを採用したのは、1987年のWindows 2.0で、 HIMEM.SYSデバイスドライバが導入されました。DR -DOS(1990年)とMS-DOS (1991年)のバージョン5.0以降では、オペレーティングシステムの一部をHMAにロードできるようになり、最大46 KiBの従来型メモリを解放することができました。デバイスドライバやTSRなどの他のコンポーネントは、上位メモリ領域(UMA)にロードできました。
80286では、一部のISAデバイス向けにMMIOメモリホール(15MiB~16MiB)が導入されました。
A20ハンドラは、高位メモリ領域へのアクセスを制御するソフトウェアです。通常、拡張メモリマネージャがこの機能を提供します。DOSでは、 HIMEM.SYSなどの高位メモリ領域マネージャがA20を管理するという追加の役割を担い、 A20のオープン/クローズのためのAPIを提供していました。DOS自体もこの領域をストレージの一部に利用することで、プログラム用に従来型のメモリをより多く解放することができました。この機能は、CONFIG.SYS構成ファイル内の「 DOS =HIGH」ディレクティブによって有効化されていました。
Intel 80486とPentium にはA20M#という特別なピンが追加され、これをローにすると、オンチップ キャッシュまたは外部メモリへのアクセスすべてにおいて物理アドレスのビット 20 がゼロになります。これは、80486 がオンチップ キャッシュを導入したため、外部ロジックでこのビットをマスクすることができなくなったため必要でした。ソフトウェアは依然としてゲートを操作する必要があり、そのためには外部周辺機器 (チップセット) を処理する必要があります。[ 4 ]
Intelの386以降のプロセッサは仮想8086モードをサポートしており、DOSアプリケーション向けに拡張メモリを実装するために必要なハードウェアが簡素化されました。QuarterdeckのQEMM製品やMicrosoftのEMM386などの拡張メモリマネージャは、特別なメモリボードを必要とせずに拡張メモリ規格をサポートしました。
386以降のプロセッサでは、QEMMのようなメモリマネージャが、ドライバやTSRのコードの大部分を拡張メモリに移動させ、拡張メモリに常駐するコードにアクセスできる小さな領域に置き換えることがありました。また、起動時に後続時よりも多くのRAMを必要とするドライバを検出するためにメモリ使用状況を分析したり、起動後に不要になったメモリを回収して再利用したりすることもありました。さらに、メモリマップドI/Oに通常使用されるメモリ領域を再マッピングすることさえありました。これらの工夫の多くは、ドライバやその他のコンポーネントの動作に関する仮定に基づいていました。事実上、メモリマネージャは、他のベンダーのコードをリバースエンジニアリングして、その場で変更することがありました。当然のことながら、このような工夫が常にうまくいくとは限りませんでした。そのため、メモリマネージャは、設定可能なオプションの非常に複雑なシステムと、選択したオプションによってPCが起動不能になった場合(頻繁に発生する)、復旧するための仕組みも組み込んでいました。
メモリマネージャのインストールと設定には、オプションの試行錯誤、マシンの度重なる再起動、結果のテストなど、何時間もかかることがあった。しかし、従来のメモリは非常に貴重だったため、PCユーザーは、その結果として30~40KiB のメモリ容量を解放できるのであれば、そのような時間を費やす価値は十分にあると感じていた。
IBM PC互換コンピュータにおいて、拡張メモリとは、8088および8086の20本のアドレス線によって課せられる1メガバイトの制限を超える、80286以降のプロセッサのアドレス空間内のメモリを指します。このようなメモリは、80286以降のプロセッサのいわゆる「リアルモード」で動作するDOSアプリケーションからは直接アクセスできません。このメモリは、80286以降のプロセッサのプロテクトモードまたは仮想モードでのみアクセス可能です。