コンピュータサイエンスにおいて、XIP(execute in place )とは、プログラムをRAMにコピーするのではなく、長期記憶領域から直接実行する手法です。これは、共有メモリの使用を拡張することで、必要なメモリの総量を削減する手法です。
その一般的な効果は、プログラム テキストが書き込み可能なメモリを消費せず、それを動的データ用に保存し、プログラムのすべてのインスタンスが単一のコピーから実行されることです。
これが機能するには、いくつかの条件を満たす必要があります。
ストレージ要件は通常、NOR フラッシュ メモリまたはEEPROM を使用することで満たされます。これらは読み取り操作用にバイト アドレス指定できますが、ほとんどのセットアップで通常のシステム RAM よりも少し遅くなります。
x86システムでは、通常、第一段階ブートローダはXIPプログラムであり、電源投入時にフラッシュチップがマッピングされるアドレスで実行されるようにリンクされています。システムRAMをセットアップするための最小限のプログラム(これは個々のボードで使用されているコンポーネントに依存し、適切なシーケンスをプロセッサハードウェアに組み込むほど汎用化することはできません)が含まれており、その後、第二段階ブートローダまたはOSカーネルをRAMにロードします。
この初期化中は書き込み可能なメモリが利用できない可能性があるため、すべての計算はプロセッサレジスタ内で実行する必要があります。このため、第一段階のブートローダはアセンブリ言語で記述される傾向があり、次のプログラムのための通常の実行環境を提供するための最小限の機能のみを実行します。一部のプロセッサでは、チップ自体に少量のSRAMを組み込んでいるか[ 1 ]、オンボードのキャッシュメモリをRAMとして使用できるようにすることで[ 2 ]、この第一段階のブートローダを高級言語で記述しやすくしています。
カーネルやブートローダの場合、アドレス空間は通常内部的に割り当てられるため、XIPを使用するには、リンカーに修正不可データと修正可能データを異なるアドレス範囲に配置するよう指示し、データに正常にアクセスできると想定するコードを実行する前に、修正可能データを書き込み可能なメモリにコピーするメカニズムを提供すれば十分です。これは、前の段階の一部として行うことも、プログラム先頭の小さなコードセグメント内で行うこともできます。
仮想メモリを提供しないシステム上で実行されるアプリケーションプログラムなど、アドレス空間が外部的に割り当てられている場合、コンパイラはデータ領域のプライベートコピーへのポインタにオフセットを追加することで、変更可能なすべてのデータにアクセスする必要があります。この場合、外部ローダーがインスタンス固有のメモリ領域の設定を担当します。
x86システムでは、通常、BIOS / UEFI ROMは電源投入時に固定メモリ空間にマッピングされ、[ 3 ] x86システムのBIOS / UEFIはXIPを使用してメインメモリを初期化します。ARMおよびRISC-V組み込みシステムでは、通常、SoC内蔵のブートROMは電源投入時に固定メモリ空間にマッピングされ、ブートROMはNANDフラッシュメモリからDas U-Bootなどの組み込みブートローダを見つけてロードすることができ、そのブートプロセスは専用のEEPROMチップを使用しません。
XIPはファイルシステムに、しばしば満たすことが困難な要件を課します。ページテーブルを持たないシステムでは、ファイル全体を連続したバイト列に格納し、断片化しないようにする必要があります。一方、フラッシュベースのファイルシステムでは、フラッシュチップの消去サイクルが最も少ないセクターにデータを分散させ、チップの 摩耗を均等化して寿命を延ばすことが目的とされることが多いです。
こうした複雑さと速度とのトレードオフにより、XIPは一般的に第一段階のブートローダ、あるいはRAMが極端に不足している場合にのみ使用されます。特に、第2世代から第4世代のビデオゲームコンソールは、 ROMカートリッジのアドレスバスとデータバスをコンソールのアドレスバスと接続します[ 4 ]。これにより、例えばAtari 2600はジョイスティックインターフェースICの128バイトのRAMのみで動作します。
Linux向けの比較的新しいファイルシステムであるAXFS(Advanced XIP File System )は、XIPに関連するいくつかの欠点、特にユーザー空間アプリケーションのインプレース実行に関する欠点を克服することを目的としています。例えば、実行可能なバイナリファイルを「XIP領域」に分割することで、前述の断片化の制限を回避できます。