
A20 (アドレスライン20 )は、 x86ベースのコンピュータシステムのシステムバスを構成する電気ラインの1つです。特にA20ラインは、アドレスバスの21番目のビットを伝送するために使用されます。
マイクロプロセッサには通常、物理アドレス空間内のワード数の2 を底とする対数に等しいアドレス ラインがあります。たとえば、4 GB のバイト アドレス指定可能な物理空間を持つプロセッサには 32 本のライン (log 2 (4 GB) = log 2 (2 32 B) = 32) が必要で、これらは A0 から A31 までの名前が付けられます。これらのラインは、送信するアドレスのビットの 0 から始まる番号にちなんで名付けられています。最下位ビットが最初であるため、ビット 0 として番号が付けられ、ライン A0 で信号が送られます。A20 はビット 20 (21 番目のビット) を送信し、アドレスが 1 MB、つまり 2 20に達するとアクティブになります。
Intel 8086、Intel 8088、およびIntel 80186プロセッサには、A0 から A19 まで番号が付けられた 20 のアドレス ラインがありました。これにより、プロセッサは 2 の20乗バイト、つまり 1 MB にアクセスできます。このようなプロセッサの内部アドレス レジスタは 16 ビットしかありませんでした。20 ビットのアドレス空間にアクセスするために、外部メモリ参照は 16 ビットのオフセットアドレスに 16 ビットのセグメント番号を追加し、4 ビット左にシフトして 20 ビットの物理アドレスを生成しました。結果のアドレスは、セグメント × 16 +オフセットに等しくなります。[ 1 ]同じ 20 ビットの物理アドレスを生成するセグメントとオフセットの組み合わせは多数あります。そのため、メモリ内の同じバイトをアドレス指定する方法はさまざまでした。[ 2 ]例えば、4096通りのセグメントとオフセットの組み合わせのうち4つを以下に示します。これらはすべて、物理アドレスが0x000FFFFF(1MBのメモリ空間の最後のバイト)であるバイトを参照しています。
最後の方法で参照すると、オフセットを1増やすとF800:8000 となり、これはプロセッサにとって適切なアドレスですが、物理アドレス0x00100000(1MBを超える最初のバイト)に変換されるため、プロセッサは実際にそのバイトにアクセスするために別のアドレスラインを必要とします。8086シリーズのプロセッサにはそのようなアドレスラインがないため、上記の21番目のビットはセットされていても破棄され、アドレスF800:8000は「ラップアラウンド」[ 1 ]し、実際には物理アドレス0x00000000を指すことになります。
IBM がIBM PC AT (1984) マシンを設計したとき、同社は新しい高性能なIntel 80286マイクロプロセッサの採用を決定した。80286 は、プロテクト モードで最大 16 MB のシステム メモリをアドレス指定できた。しかし、CPU はリアル モード(スタートアップ モード) で 8086 の動作をエミュレートし、プロテクト モード用に書かれていないオペレーティング システムやプログラムを実行できるようにすることになっていた。しかし、80286 はリアル モードでは A20 ラインをゼロに強制しなかった。したがって、F800:8000の組み合わせは物理アドレス0x00000000ではなく、アドレス0x00100000を指すようになった。結果として、アドレス ラップ アラウンドに依存するプログラムは動作しなくなった。こうしたプログラムとの互換性を維持するため、IBM はマザーボードの問題を修正することを決定した。
これは、プロセッサとシステムバス間のA20ラインに論理ゲートを挿入することで実現され、 Gate-A20と名付けられました。Gate-A20はソフトウェアによって有効化または無効化することができ、アドレスバスがA20からの信号を受信するかどうかを選択できます。ラップアラウンドに依存する古いプログラムの実行では、Gate-A20は非通過に設定されています。起動時、BIOSはシステムメモリ全体をカウントしてテストする際にGate-A20をまず有効化し、その後、オペレーティングシステムに制御を移す前に無効化します。
当初、論理ゲートはIntel 8042キーボードコントローラに接続されたゲートでした。[ 1 ]制御は比較的遅いプロセスでした。その後、このラップアラウンドを必要とするプログラムと、システムメモリ全体にアクセスするプログラムとのマルチタスクをより効率的に実行できるように、他の方法が追加されました。A20ラインを制御する方法は複数あります。[ 3 ]
A20を切断しても、1MBを超えるメモリアクセスはすべてラップされるわけではなく、1~2MB、3~4MB、5~6MBなどの範囲のアクセスのみがラップされます。リアルモードソフトウェアは1MBをわずかに上回る領域のみを処理するため、Gate-A20ラインで十分でした。
Gate-A20 ラインを有効にすることは、保護モードの x86 オペレーティング システムがブートアップ プロセスで実行する最初のステップの 1 つであり、多くの場合、ブートストラップからカーネルに制御が渡される前に行われます(たとえば、 Linuxの場合)。
Intel 80386で導入された仮想8086モードは、プロセッサの仮想メモリ機能を用いてA20のラップアラウンドをシミュレートすることを可能にします。物理メモリは複数の仮想アドレスにマッピングされます。つまり、仮想メモリの最初のメガバイトにマッピングされたメモリは、仮想メモリの2番目のメガバイトにも再びマッピングされる可能性があります。オペレーティングシステムはゲートA20への変更を傍受し、仮想メモリのアドレス空間に対応する変更を加える可能性があり、これもゲートA20ラインのトグルの効率を無関係にします。
A20 ラインの制御は、IBM PC アーキテクチャの成長過程のある段階では重要な機能でした。これは、ソフトウェアを大幅に変更することなく、リアルモードで追加の 65,520 バイト (64 KB - 16 バイト) のメモリへのアクセスを追加したためです。
おそらく「ハック」だったと思われるA20ゲートは、もともとマザーボード上のキーボードコントローラーの一部であり、必要な動作に応じてゲートを開いたり閉じたりすることができました。[ 4 ]
Intel 8086との完全な互換性を維持するため、A20ゲートは2008年までIntel CPUに存在していました。[ 5 ]このゲートは起動直後に閉じられていたため、プロテクトモードのオペレーティングシステムは通常、起動プロセスの早い段階でA20ゲートを開き、二度と閉じないようにしていました。このようなオペレーティングシステムには、A20ゲートを閉じたままにする互換性上の理由はなく、ゲートを開くことで利用可能な物理アドレスの全範囲にアクセスできるようになりました。
Intel 80486とPentiumには、 A20M#という特別なピンが追加されました。このピンをLowにアサートすると、すべてのオンチップキャッシュ(または外部メモリ)アクセスにおいて、物理アドレスのビット20が0に強制されます。これは、80486がオンチップキャッシュを導入したため、外部ロジックでこのビットをマスクすることができなくなったため、必要な機能でした。ソフトウェアは依然としてゲートを操作する必要があり、そのためには外部周辺機器(チップセット)とのやり取りが必要になります。[ 6 ]
PCシステム設計ガイドPC 2001では、A20ラインの互換性が削除されています。「A20M#生成ロジックがシステムにまだ存在する場合、このロジックは、I/Oポート92のビット1へのソフトウェア書き込みによってプロセッサにA20M#がアサートされないように終了する必要があります。」[ 7 ]
A20ゲートのサポートは、Nehalemマイクロアーキテクチャで変更されました(一部の情報源では、A20サポートが削除されたと誤って主張しています)。CPUがA20ビットをマスクするかどうかの信号を受信する専用のA20M#ピンを持つのではなく、周辺ハードウェアからCPUへ特別なバスサイクルを使用して情報が送信されるように仮想化されました。[要出典]ソフトウェアの観点から見ると、このメカニズムは以前と全く同じように機能し、オペレーティングシステムはA20マスクを無効にするために、外部ハードウェア(そして前述のバスサイクルをCPUに送信する)をプログラムする必要があります。[要出典]
インテルはHaswell以降、A20ゲートのサポートを終了しました。2013年6月の『インテル システムプログラマーズマニュアル Vol. 3A』の271ページには、「A20M#の機能は主に古いオペレーティングシステムで使用され、最新のオペレーティングシステムでは使用されません。新しいIntel 64プロセッサでは、A20M#が存在しない場合があります。」と記載されています。[ 8 ]
A20ハンドラは、IBM PCの メモリマネージャソフトウェアであり、ハイメモリ領域(HMA)へのアクセスを制御します。通常、この機能は拡張メモリマネージャによって提供されます。A20ハンドラは、マイクロプロセッサの21番目のアドレスラインであるA20ラインにちなんで名付けられています。
DOSでは、 HIMEM.SYSなどの HMA マネージャは、A20 を管理するという「追加タスク」を担っています。HIMEM.SYS はA20 をオープン/クローズするためのAPIを提供していました。DOS 自体は、この領域をストレージニーズの一部に使用でき、プログラムがより多くのコンベンショナルメモリを使用できるようになっています。この機能は、CONFIG.SYSDOS=HIGH設定ファイルのまたはHIDOS=ONディレクティブによって有効化されていました。
1980年以来、アドレスラップは86-DOSとMS-DOSで内部的に使用され、プログラムセグメントプレフィックス(PSP)( CP/M-80のゼロページに部分的に似ている)のオフセット+5から+9のDOS CALL 5エントリポイント(オフセット+5から+7のCP/M-80スタイルのCALL 5 BDOS APIエントリポイントをエミュレートする)を実装しました。[ 9 ] [ 10 ]これは特に、シアトルコンピュータプロダクツのTRANS86などのアセンブリ言語トランスレータ[ 9 ]を介してCP/M-80から機械翻訳されたプログラムで利用されました。[ 11 ]このエントリポイントが参照するCALL 5ハンドラは、マシンの物理アドレス0x000000C0に常駐しています(そのため、INT 30hに予約されている割り込みサービスルーチンエントリポイントの4バイトと、x86リアルモード割り込みベクターテーブル内のINT 31hの最初のバイトが重複しています)。[ 12 ] [ 13 ] [ 14 ]ただし、アプリケーションプログラムが実行できるメモリのすぐ上にオペレーティングシステムをロードするCP/M-80の設計により、ゼロページのオフセット+6~+7に格納されている8080 / Z80の16ビットターゲットアドレスは、意図的に最初のメモリセグメントのサイズとして解釈される可能性もあります。[ 9 ]これをDOSの8086セグメント:オフセットアドレス指定方式でエミュレートするためには、ファーコールエントリポイントの16ビットオフセットがこのセグメントサイズ(つまり0xFEF0)と一致する必要がありました。このセグメントサイズはPSPのオフセット+6から+7に格納され、CALL 5の一部と重複しています。[ 13 ] [ 14 ]これらの要件を調和させる唯一の方法は、0xFEF0に加算するとアドレスが0x001000C0になり、8086では0x000000C0にラップアラウンドするセグメント値を選択することでした。[ 15 ] [ 12 ] [ 14 ]
ラップアラウンドが発生し、このインターフェースを使用するDOSプログラムが動作するためには、A20を無効にする必要がありました。HMAに自身の一部を移動できる新しいDOSバージョンは、通常、 HMAのFFFF:00D0(これも物理アドレス0x001000C0に解決されます)にあるエントリポイントのコピーを作成し、A20の状態に関係なくインターフェースが動作できるようにします。[ 14 ] [ 16 ]
CALL 5インターフェースを使うことが知られているプログラムとしては、Small-CコンパイラのDOS版がある。[ 17 ]また、マイクロソフトのWord 3.0 (1987年)のSPELLユーティリティも、CALL 5インターフェースの設定を必要とするプログラムの1つである。[ 18 ] サン・マイクロシステムズのPC-NFS(1993年)もCALL 5の修正を必要とする。[ 16 ]
また、プログラムスペースを節約するために、[ 1 ]一部のBIOSおよびDOSプログラマーは、たとえば、プログラムデータ(物理アドレス0x000F8000 ~0x000FFFFFを指すF800:0000~F800:7FFFなど)にアクセスできる1つのセグメントと、最初のメモリセグメント(アドレスF800:8000~F800:FFFFで、物理アドレス0x00000000~0x00007FFFを指す)に配置されたI/Oデータ(キーボードバッファなど)にアクセスできるセグメントを持つなどのトリックを使用しました。
このトリックは、コードが低メモリ(RAM の最初の 64 KB)で実行されない限り機能します。これは、高負荷機能のない古い DOS バージョンでは常に当てはまっていた条件です。
DOSカーネルが高位メモリ領域に再配置されたため、低位メモリがプログラムに利用可能となり、ラップアラウンドに依存するプログラムが失敗するようになりました。[ 19 ] DOSの新しいバージョンの実行可能ローダーは、影響を受けるプログラムの一般的なタイプを検出し、低位メモリでも機能するようにオンザフライでパッチを適用するか[ 20 ]、実行を渡す前に最初の64KBより上にロードします。[ 20 ]自動的に検出されないプログラムの場合は、LOADFIX [ 21 ]またはMEMMAX -L [ 21 ]を使用して、プログラムを最初の64KBより上にロードするように強制できます。
このトリックはIBM/Microsoft Pascal自体と、それでコンパイルされたプログラムで利用されており、[ 22 ] [ 23 ] [ 10 ] [ 17 ]これにはMicrosoftのMASMも含まれる。[ 17 ]これを使用した一般的な開発ユーティリティとしては、 RealiaのSpacemaker [ 20 ] ( 1982年にRobert BK Dewarによって書かれ、 Norton Utilitiesの初期のバージョンを圧縮するために使用された[ 24 ] [ 25 ] [ 26 ] [ 27 ])やMicrosoftのEXEPACK [ 19 ] [ 20 ] [ 1 ] [ 28 ] [ 17 ](1985年にReuben Bormanによって書かれた)などの実行可能ファイル圧縮プログラム、およびMicrosoftのLINK 3.02以降で同等の/E[XEPACK]オプションがある。[ 19 ] [ 1 ] [ 28 ] [ 26 ] EXECPACKで処理されたプログラムは「パックされたファイルが壊れています」というエラーメッセージを表示します。[ 1 ] [ 20 ] [ 28 ]
問題のある解凍ルーチンをリスタブによって置き換えたり、元のファイルの展開と復元を試みたりして、 圧縮された実行可能ファイルを変更するためのさまざまなサードパーティ製ユーティリティが存在します。
最近のレガシーBIOS ブートローダー( GNU GRUBなど)はA20ラインを使用します。[ 3 ] UEFIブートローダーは32ビット 保護モードまたは64ビット ロングモードを使用します。
–0047。A20M#はプロセッサで常にデアサート(ハイレベルにプルアップ)されます。
8080/Z80プログラムを8086コードに
簡単に変換できるようにするために提供されており
、新規プログラムには推奨されません。[...] メモリサイズ。これはプログラムセグメントで使用可能なバイト数です。[...]
(41ページ)
[...] 8086用に書かれたプログラムの中には、正常に動作するために[アドレスラップアラウンド]に依存しているものがあります。残念ながら、80286のリアルモードではメモリアドレスが1MBを超えるため、下位メモリアドレスにラップされません。その結果、
Microsoft PASCAL
で書かれたプログラムやMS-DOSの「Call 5」機能を使用するプログラムなどは、標準の80286システムでは動作しません。 [...] たとえば、
64K 未満のメモリ
には PASCAL プログラムはロードされず、1 メガバイトを超える下位のメモリ位置 (アドレス 100000h または 100010h など) には特別な命令が配置されます。 [...]
{{cite web}}: CS1 maint: bot: 元のURLステータス不明(リンク)
[...]
CP/M-86
へのアクセス[...] CP/M-86 にアクセスするには、機能コードを CL レジスタに配置し、バイト パラメータを DL レジスタに配置するかワード パラメータを DX レジスタに配置し、データ セグメントを DS レジスタに配置し (データ セグメントは通常、変換されたプログラムでは変更されません)、ソフトウェア割り込み
INT #224
を実行する必要があります。結果は、バイト値の場合は AL レジスタに返され、ワード値の場合は AX レジスタと BX レジスタの両方に返されます。ダブルワード値は、BX レジスタのオフセットと ES レジスタのセグメントと共に返されます。したがって、プログラムを
CP/M-80から CP/M-86 に変換するには、位置 5 への呼び出しをソフトウェア割り込み INT #224 に置き換える必要があります。もう 1 つの必要な変更は、
ウォーム ブート
に関するものです
。 CP/M-80では、位置0へのジャンプを行う関数コード0のシステムコールによってウォームブートにアクセスできます。しかし、CP/M-86では位置0へのジャンプはサポートされていません。そのため、プログラムを正しく動作させるには、変換後のプログラム内でこのプログラム終了を変更する必要があります。位置5への呼び出しをINT #224に置き換え、ウォームブートの変更を行い、レジスタが正しくマッピングされていれば、変換後のプログラムでCP/M-86のシステム関数にアクセスする際に問題はほとんど発生しません。[...]
MS-DOS
へのアクセス[...] MS-DOSには、システムにアクセスするためのソフトウェア割り込み
INT #33
を介した「推奨」メカニズムがありますが、「既存」プログラム向けに、少なくとも0~36の範囲の関数については、CP/M-80の呼び出し規約と互換性のある追加のメカニズムも提供されています。許可された関数範囲内のシステムコールに関しては、プログラマはレジスタを正しくマッピングする以外に、MS-DOSで実行するために翻訳されたプログラムに対して何もする必要はありません。MS-DOSはCP/M-80のウォームブート機能もサポートしています。MS-DOSでアドレス0にジャンプすると、ソフトウェア割り込み
INT #32が実行されます。
これは機能的にはプログラムの終了であり、プログラムを終了する通常の方法です。 [...][2] [3] [4] [5] [6] [7 ] [8 ] [ 9] [10] [11] [12] [13] [14] [15](13ページ)
[...]
86-DOS
、ひいては
PC DOS
/
MS-DOSでは巧妙なトリックが使われていた。PSPのオフセット5
の
バイトに
はファーコールオペコード(9Ah)が含まれていた。PSPのオフセット6のワードには、プログラムセグメントサイズを示す適切な値と、ファーコールのオフセット部分が含まれていた。ファーコールのセグメント部分として機能するオフセット8のワードは、オフセットと組み合わせることでラップアラウンド(
8086
CPUのよく知られた機能)し、割り込みベクター30hを含むアドレス0:C0hを指すように作られていた。 [...] 互換性インターフェースの問題は、ロードされたプログラムの使用可能なメモリが実際には64KB未満である場合に発生します。その場合、PSPオフセット6のワードに正しい値が含まれない可能性がありますが、CALL 5インターフェースは動作します。オフセット5の命令はCALL 0:C0hとなり、報告されるプログラムセグメントサイズはC0hになります。DOSがなぜこのように動作するのかは不明ですが、DOS 5.0以降のバグと思われます。DOS 4.0以前のバージョンでは、セグメント部分が0:C0hに折り返されるように調整されていました。これは、プログラムセグメントサイズが段落揃えされている限り機能し、実際、段落揃えになっています。[...]
[...] 説明するにはあまりにも奇妙で複雑なプロセスによって、セグメント化アドレスは2つの目的を果たすように設定されます。DOS関数ディスパッチャを指すだけでなく、オフセット部分はコードセグメントの使用可能範囲(最大16進数FFF0、64KBより16バイト少ない)を示します。アドレスのオフセット部分、つまり私たちが関心を持つ部分は、PSP内のオフセット6に位置し、オフセット5にある命令のオペコードの後に続きます。つまり、DOSがプログラムに提供できるメモリが64KB未満の場合、このフィールドを使って使用可能なバイト数を知ることができます。これは、ほとんど、あるいはすべてのウィンドウシステムやマルチタスクシステムで機能するはずです。[...](426ページ)
[...] BIOSINIT.A86 1.40 93/11/11 12:25:29 [...]
VDISK
ヘッダーの変更 [...] BIOSINIT.A86 1.39 93/11/08 23:19:22 [...] SetupHMAがCALL5の初期化を実行 [...]
PC-NFS
のCALL5リンク用に
ハイメモリ
のJMPFを修正[...]
[16](注:OpenDOS 7.01 MRS:IBMBIO\BIOSINIT.A86 SetupHMA)
A20ラインを有効にしたままにしておくと、ラップアラウンドを想定するプログラムで問題が発生します。[...] そのようなプログラムの一つが、元々
EXEPACKされたファイルに含まれていた
Microsoft
独自のリンカーの解凍ルーチンでした
。DOS逆アセンブリ分野のベテランであり、シェアウェアDOSMAX
UMB
メンテナンスユーティリティの作者であるフィリップ・ガードナー氏によると、DOS 5.0の導入直後から至る所で表示されるようになった悪名高い「Packed File Corrupt(パックされたファイルが壊れています)」エラーメッセージは、A20ラインが有効になっていることと、元の解凍ルーチンがセグメントラップアラウンド効果を利用して圧縮ファイルを適切に展開していたことが直接の原因です。[...]
(xviii+856+viページ、3.5インチフロッピー[17] ) 訂正: [18] [19] (注: 本書の350ページに、問題のあるEXEPACK解凍ルーチンの内部動作に関する詳細な説明があります。)
[...]
DR Concurrent DOS 386
(1988年7月8日以降)は、
EXEPACKされた
プログラムを64Kマーク以上、つまり「
最低メモリ
」の外側にロードします。これは、プログラムの環境を含むメモリブロックを拡張することによって行われます。[...]
DR DOS 5.0以降は、
.EXE
形式のプログラムを常に
フィックスアップなしでロードし、(1990年5月25日以降)
SpaceMaker
で圧縮された
.COM
形式のプログラム(したがって、9Ch 55h(PUSHF/PUSH BP)から始まる)も、EXEPACKのラップアラウンドバグを回避するために64Kマーク以上をロードします。これは、プログラムの環境を含むメモリブロックを拡張することによって実現され、1989年12月14日以降は必要に応じて複数のフィラーを割り当てるようになりました。MCBに格納されている親プログラムの名前が「WIN」の場合、この環境拡張コードは無効になります。これは、
WIN.COMが
KERNEL.EXE(再配置項目なし)を起動する際のパフォーマンスを向上させるためです。 [...]
MS-DOS
/
PC DOS 5.0
+[...] カーネルは、.EXE 形式の実行ファイル内の様々なコードシーケンスをスキャンし、EXEPACK されたファイルの様々なバージョンにパッチを適用して、(DOS が HMA にある場合
)
最低メモリ、つまり 64KB 未満のロードセグメントで実行できるようにします。そうでない場合、「Packed file corrupt」と表示されます。コードは、コードのエントリポイント [...] が 0002h 未満でないことを確認し、エントリポイントの直前の WORD を読み取ります [...] この WORD が 5242h("RB")の場合、ファイルは EXECPACK されていると想定されます。次に、コードは、この "RB" 署名からのオフセットで、複数のコードシーケンスの組み合わせのいずれかを探します。[...] MS-DOS 5.0+[...] カーネルは、未知のクラスの
.COM
実行ファイルをスキャンします。ファイル内にこれらのシグネチャが見つかった場合、ディスクバッファ情報テーブル(表「DOS 5.0-6.0 ディスクバッファ情報」を参照)のオフセット18hにあるA20カウントダウン変数が10に設定され、その後、この回数のINT 21h呼び出しが行われた後、A20が無効化されます。おそらく、この種のプログラムは実行開始後しばらくA20を無効化する必要があると考えられます。(INT 21h/AH=25hおよびAH=49hへのエントリ時にも同様の動作が発生します。)[...]
{{cite book}}:|work=無視されました (ヘルプ)NWDOSTIP.TXT (注: 提供されたリンクは、コレクションの一部であるのHTML変換バージョンを指していますMPDOSTIP.ZIP。) [20]
[...] DX は最終的な DS です(負の値になる場合があります)[...] 最終的な DS 値(負の値になる場合があります)[...]
[...]
SPACEMAKER
および TERMULATOR、 Realia, Inc. が販売する
IBM PC 用コモディティ ソフトウェア (
PC DOS
ファイル圧縮ユーティリティおよび
VT-100エミュレータ)。RBK
Dewar
(1982-1983)、8088 アセンブリ言語、8,000 行 [...]
[...] リンカーの/Eオプションは、非圧縮EXEファイルと論理的に同等のEXEファイルを生成するはずです。現在のバージョンでは[...] AXが上書きされます。EXEファイルへのエントリ時のAXには明確な意味(パラメータのドライブの有効性を示す)があるため、非圧縮イメージにそのまま渡される必要があります。この 1 つの非常に明白なインターフェース ルール違反を考慮すると、他にも違反がある可能性がありますが、私はそれ以上調査するつもりはありません [...] 私は、
EXEPACK
オプションに似たような機能を実行する
Realia SpaceMaker
プログラムを作成しました(ただし、言うまでもなく、この特定の [...]