web-dev-qa-db-ja.com

完全エミュレーションと完全仮想化

フルエミュレーションでは、I/Oデバイス、CPU、メインメモリが仮想化されます。ゲストオペレーティングシステムは、物理デバイスではなく仮想デバイスにアクセスします。しかし、完全仮想化とは正確には何ですか?それは完全なエミュレーションと同じですか、それともまったく異なるものですか?

33
user44444444

エミュレーションと仮想化は関連していますが、同じではありません。

エミュレーションは、ソフトウェアを使用して、異なる実行環境またはアーキテクチャを提供しています。たとえば、WindowsボックスでAndroidエミュレータを実行しているとします。Windowsボックスには、Androidデバイスと同じプロセッサがありません。エミュレーターは実際にソフトウェアを介してAndroidアプリケーションを実行します。

仮想化とは、同じ物理環境で実行されている複数の仮想環境間に仮想バリアを作成することです。大きな違いは、仮想化環境が同じアーキテクチャであるということです。仮想化アプリケーションは、物理デバイスに変換される仮想化デバイスを提供する場合があり、仮想化ホストは、各デバイスまたはデバイスの一部にアクセスできる仮想マシンを制御します。ただし、実際の実行は、ソフトウェアを介さずに、ほとんどの場合、ネイティブで実行されます。したがって、仮想化のパフォーマンスは通常、エミュレーションよりもはるかに優れています。

Java、.NET、またはFlashコードを実行する仮想マシンなどの別の概念もあります。それらは実装ごとに異なる可能性があり、エミュレーションまたは仮想化、あるいはその両方の側面が含まれる場合があります。たとえば、JVMはJavaバイトコードを実行するメカニズムを提供します。ただし、JVM仕様では、バイトコードをソフトウェアで実行する必要があることや、ネイティブコードにコンパイルする必要があることは規定されていません。 。各JVMは独自の機能を実行できます。実際、ほとんどのJVMは、必要に応じてエミュレーションを使用することと、必要に応じてJITを使用することの両方を組み合わせて実行します(ホットスポットJITは、Sun/OracleのJVMと呼ばれるものです)。

30
Samuel Neff

フルエミュレーションでは、I/Oデバイス、CPU、メインメモリが仮想化されます。

いいえ、それらはソフトウェアでエミュレートされます。エミュレートとは、それらの動作がソフトウェアで完全に複製されることを意味します。

しかし、完全仮想化とは正確には何ですか?

仮想化では、プロセスを高速化するために、ハードウェア上でできるだけ多くのコードを実行しようとします。これは、ホストのグローバル状態を変更する可能性があるため、 カーネルモード で実行する必要のあるコードで特に問題になります(マシン ハイパーバイザーまたはVMM が実行されている) )、それによって他の仮想マシンに影響を与えます。

4
Jacob

エミュレーションも仮想化もなしで、コードはハードウェア上で直接実行されます。その命令はCPUによってネイティブに実行され、そのI/Oアクセスはハードウェアに直接アクセスします。


仮想化とは、ゲストコードが少なくとも一部の時間ネイティブで実行され、仮想マシンの外部で実行されているホストコードにのみトラップされる場合です(例:- ハイパーバイザー )特権操作またはI/Oアクセス用。

これらのトラップ(別名VM exits)を処理​​するために、VMは実際にはemulateゲストがやろうとしていたことかもしれません。ゲストは単純なネットワークカード用のデバイスドライバーを実行している可能性がありますが、NICは純粋にVM内のソフトウェアに実装されています。VMがパスを使用した場合-ゲストのI/Oアクセスをホスト上の実際のネットワークカードに送信することで、そのハードウェアが仮想化されます(特に、複数のゲストが一度に使用できるようにした場合は、それ以外の場合は、実際にはそれを提供するだけです)。仮想化するのではなく、1人のゲストに。)

仮想化のハードウェアサポート( IntelとAMDの個別のx86仮想化拡張機能など )により、ゲストは、ページテーブルのメモリマッピングを変更するなど、通常はマシン全体に影響を与えることができます。したがって、VM exitをトリガーし、VMをゲストが何をしているかを把握し、外部から変更して結果を達成する代わりに、CPU追加の翻訳レイヤーが組み込まれているだけです(ソフトウェアベースの仮想化とハードウェア支援の仮想化のより優れた、しかしより長い説明については、リンクされたwikiの記事を参照してください)。


純粋なエミュレーションは、ゲストコードがネイティブに実行されることはなく、ホストの「実際の」ハードウェアを認識しないことを意味します。 エミュレータはホストへの特権アクセスを必要としません。 (デバイスのパススルーのために、またはゲストが実際にホストと同じネットワークに接続されているように見せるために生のネットワークソケットのために、ホストへの特権アクセスが必要な場合があります)。

そもそもホストハードウェアはARM命令を実行できないため、x86ホストで実行されているARMエミュレータは常にこのように動作する必要があります。

ただし、たとえば、x86ホストでx86ゲストをエミュレートすることはできます。ゲストアーキテクチャとホストアーキテクチャが一致するという事実は、エミュレータがその事実を利用する必要があるという意味ではありません。


たとえば、 BOCHSはx86 PCエミュレーターです ポータブルC++で記述されています。その主な用途の1つは、ブートローダーとOSのデバッグです。

BOCHSは、x86ホストで実行されているかどうかを気にしません。これは、バイナリファイル(ディスクイメージ)を読み取り、ウィンドウ(ゲストビデオメモリのコンテンツ)に描画する単なるC++プログラムです。ホストに関する限り、JPGビューアやゲームと特に違いはありません。

一部のエミュレーターは、バイナリ変換を使用してゲストコードをホストコードにJITコンパイルしますが、これは仮想化ではなくエミュレーションです。 http://wiki.osdev.org/Emulator_Comparison を参照してください。

BOCHSは、バイナリ変換を行わずにゲスト命令を直接読み取ってデコードするため、比較的低速です。しかし、これを可能な限り効率的に行おうとします。ゲストの状態を効率的に追跡するために使用するいくつかのトリックについては、 Bochsが内部でどのように機能するか を参照してください。エミュレーションは、x86以外のハードウェアでx86ソフトウェアを実行するための唯一のオプションであるため、高性能エミュレーターがあると便利です。 BOCHSには、非常に賢く経験豊富なエミュレータ開発者が取り組んでいます。特に、エミュレーションの最適化に関する興味深い記事をいくつか持っているDarek Mihocka 彼のサイト

1
Peter Cordes

これは私自身の質問に答える試みです。

システム仮想化:理解IO仮想化とハイパーバイザーの役割

仮想化

概念としての仮想化により、複数の/多様なアプリケーションが、お互いを意識することなく、同じ基盤となるハードウェア上で共存できるようになります。

例として、Windows、Linux、Symbianなどの本格的なオペレーティングシステムとそれらのアプリケーションは、同じプラットフォーム上で共存できます。すべてのコンピューティングリソースが仮想化されます。

これが意味するのは、前述のマシンのいずれも物理リソースにアクセスできないということです。物理リソースにアクセスできる唯一のエンティティは、仮想マシンモニター(別名ハイパーバイザー)と呼ばれるプログラムです。

今、これは重要です。よくお読みになり、読み直してください。

ハイパーバイザーは、上記の各マシンに仮想化環境を提供します。これらのマシンは物理ハードウェアではなく仮想化ハードウェアにアクセスするため、仮想マシンと呼ばれます。

例として、Windowsカーネルは物理タイマー(システムリソース)を開始したい場合があります。タイマーがメモリマップドIOであると仮定します。 Windowsカーネルは、タイマーアドレスに対して一連のロード/ストア命令を発行します。非仮想化環境では、これらのロード/ストアにより、タイマーハードウェアがプログラミングされます。

ただし、仮想化環境では、これらのロード/ストアベースの物理リソースへのアクセスにより、トラップ/障害が発生します。トラップはハイパーバイザーによって処理されます。ハイパーバイザーは、Windowsがタイマーをプログラムしようとしたことを認識しています。ハイパーバイザーは、各仮想マシンのタイマーデータ構造を維持します。この場合、ハイパーバイザーは、Windows用に作成したタイマーデータ構造を更新します。次に、実際のタイマーをプログラムします。タイマーによって生成された割り込みは、最初にハイパーバイザーによって処理されます。仮想マシンのデータ構造が更新され、仮想マシンの割り込みサービスルーチンが呼び出されます。

簡単に言うと、Windowsは、非仮想化環境で実行するすべてのことを実行しました。この場合、そのアクションにより、実際のシステムリソースは更新されませんが、仮想リソース(上記のデータ構造)が更新されます。

したがって、すべての仮想マシンは、基盤となるハードウェアにアクセスしていると見なします。実際には彼らには知られていませんが、物理ハードウェアへのすべてのアクセスはハイパーバイザーによって仲介されます。

上記のすべてがフル/クラシック仮想化です。最新のCPUのほとんどは、従来の仮想化には適していません。トラップ/障害はすべての命令に適用されるわけではありません。そのため、ハイパーバイザーは最新のデバイスでは簡単にバイパスされます。

ここで準仮想化が発生します。仮想マシンのソースコード内の機密性の高い命令は、ハイパーバイザーの呼び出しに置き換えられます。上記のロード/ストアスニペットは、次のような呼び出しに置き換えることができます。

Hypervisor_Service(Timer Start, Windows, 10ms); 

エミュレーション

エミュレーションは仮想化に関連するトピックです。 ARM用にコンパイルされたプログラムがATMELCPUで実行されるシナリオを想像してみてください。ATMELCPUは、各ARM命令を解釈し、エミュレートするエミュレータプログラムを実行します。 ATMELプラットフォームで必要なアクション。したがって、エミュレーターは仮想化された環境を提供します。

この場合、システムリソースの仮想化は、トラップアンド実行モデルを介して実行されません。

1
Raj

仮想化は、コンピュータアーキテクチャのさまざまな層で発生する可能性があります。1:アプリケーション、2:ライブラリ、3:オペレーティングシステム、4:ハードウェアアブストラクション(HAL)、5:命令セットアーキテクチャ(ISA)です。後者の層の下にはハードウェアがあります。通常、特定のレイヤーは、下位​​レイヤーがそのインターフェースで公開する命令を利用することにより、下位レイヤーからのサービスを利用します。
特定のレイヤーがすぐ下のレイヤーをスキップして下位レイヤーからの命令を利用できるという意味で、サービスの使用はレイヤーと厳密には関連していないことに注意してください。例として、アプリケーションは、ライブラリとO.Sをスキップして、特定の命令をHALレイヤーに直接提供する場合があります。レイヤー。

「命令をエミュレートする」とは、コンピュータアーキテクチャ(仮想)の特定の層を対象とした命令をインターセプトして、異なるコンピュータアーキテクチャ(非仮想)の同じ層のシーケンス(1つ以上)の命令にマッピングすることを意味します。 )。コンピュータアーキテクチャのさまざまな層に仮想化層を配置することができます。この点で混乱が生じる可能性があります。例として、ハードウェアアブストラクションレイヤー(VMware、VirtualBoxなど)のレベルで仮想化する場合、仮想レイヤーはHALレイヤーとオペレーティングシステムレイヤーの間に配置されます。オペレーティングシステムは仮想HALレイヤーの命令を利用し、特定の仮想ISA(命令セットアーキテクチャ)はハイパーバイザーによって物理システムのISA)にマップされます。すべての命令がエミュレートされるとき、仮想化の特殊なケースである完全なエミュレーションについて話します。仮想化では、パフォーマンス上の理由から、非仮想層の命令をできるだけ直接実行する層を作成するのが一般的です。たとえば、仮想化レイヤーはオペレーティングシステム(オペレーティングシステムレベルでの仮想化)の上に配置されます。この場合、仮想マシンはコンテナ(Dockerなど)という名前になります。これには、アプリケーションからOS(含まれる)までのレベルが含まれます。

結論として、エミュレーションは単一の命令に関連していますが、「完全なエミュレーション」は、特定のレイヤーのすべての命令をインターセプトしてマップするときに発生します。通常、「完全エミュレーション」という用語は、仮想化レイヤーがISAレベル(可能な限り低いレベル)に配置されている場合に使用されます。この場合、仮想マシンには、アプリケーションからISA、およびすべてのISAはインターセプトされ、マッピングされます。これは、Ciscoルーター(QEMUなど)や90年代のビデオゲームコンソールなど、まったく異なるアーキテクチャを持つニッチな製品を仮想化するために使用されます。通常の一般的に利用可能なコンピュータ。ただし、他のレベルでも「完全なエミュレーション」が行われる場合があり、これは通常は必要ありません。

0

最近の回答:

私の調査から、これは概念がどのように現れるかを理解するためのより良い応答であると言えます。

emulationの最初の概念は、実際には最初のコンピューターであるColossusにまでさかのぼります。これは、1941年に英国政府によって、ナチスのエニグマコードマシンの機能を模倣するために使用されました。エミュレーション理論は1962年に開発され、3つの異なる角度から作業する3人のIBMエンジニアによって考案されました。

エミュレーション模倣動作ターゲットのを意味します。これはemu8086エミュレータのようなハードウェアにすることも、あるネットワークポートからのサービスのエミュレーションのようなソフトウェア。

ターゲットによって提供される一連の関数を模倣したいが、内部メカニズムには興味がないかもしれません。

なぜあなたはそれが欲しいのですか?その機能を制御するため。なぜコントロールするのですか?ここで議論される非常に大きな主題である複数の理由のために。しかし、あなたは物事の背後にいたいということを覚えておいてください。

しかし、そのようなプロセスはパフォーマンスにコストがかかります。他の多くの命令が実行される命令があります。たぶん、あなたはその指示のいくつかだけを制御することに興味があります。そのため、一部の命令をネイティブで実行できるようにしたいと思います。

では、この命令の実行がすべてネイティブになるとどうなりますか?次に、理想的な仮想化があります。任意のソフトウェアを仮想化できますが、今日の傾向は、オペレーティングシステムの仮想化からアプリケーションの仮想化に移行することです。また、このソフトウェアはハードウェアごとに実行が異なるため、いくつかの命令もエミュレートする必要があるため、理想的と言えます。今日の仮想化テクノロジーのほとんどは、仮想化だけでなくエミュレーションにも関係していることを理解することが重要です。

また、エミュレーションから仮想化への移行では、仮想化はソフトウェアのみを入力として受け入れるため、システムの入力が削減されることに注意してください。これらの命令フローのコントローラーの名前はHyperVisorです。

0
MSD561

仮想化とエミュレーションはほとんど同じです。これらの2つの言葉が示唆する1つの根本的な概念があります。つまり、これらの2つの単語は1つのことの側面です。これは、 [〜#〜] qemu [〜#〜] 、ハードウェアを実行するクイックエミュレータ仮想化で示されています。

その1つをシミュレーションと考えることができます。シミュレーションは 紛らわしい 単語になることもあります。

まず、単語の一般的な意味を定義できます。

  • シミュレーション:あるものに別のことをさせる。
  • エミュレーション:あるシステムに別のシステムを正確に複製させる。
  • 仮想化:別のシステム内でのシステムの実行を許可します。

ここで、すべての単語がほぼ同じことを意味することを示します。たとえば、シミュレーションでは、あるシステムのレプリカを別のシステムで作成しています。これがエミュレーションの一般的な意味です。仮想化では、仮想化されたシステムを実際のシステムのように動作させる必要があります。つまり、実装が異なり、ハードウェアを正確に「エミュレート」しない場合でも、理想的にはレプリカのように機能します。それはシミュレーションとほとんど同じです。エミュレーションでは、別のシステムなどをシミュレートします。

したがって、単語は多少互換性があることがわかります。根底にある概念はシミュレーションです。

オペレーティングシステムの仮想化(「仮想マシン」)などの仮想化では、オペレーティングシステムのように機能するシステムを作成しています。パフォーマンスとセキュリティのために、基盤となるハードウェアやハイパーバイザーなどのトリックを使用する場合があります。しかし、結局のところ、それはオペレーティングシステムの単なるシミュレーションです。通常、「仮想マシン」という言葉が使用されている場合、それは(エミュレーターのように)マシンの正確なレプリカではありません。実際のオペレーティングシステムで期待どおりにプログラムを実行できるようにするだけで十分です。

エミュレーションでは、通常、シミュレーションが「正確」であることを意味します。ハードウェアエミュレーションでは、ハードウェアシステムのすべての機能を複製します。これは、ハードウェアのシミュレーションを作成したことを意味します。ハードウェアの仮想化を作成したと言えますが、ここで仮想化が少し異なります。仮想化とは、分離された環境を作成することを意味しますが、エミュレーションが必ずしも意味するわけではありません。したがって、ハードウェアエミュレーターは、ハードウェア自体と同じインターフェイスをハードウェアに提供しますが、エミュレーターの実装はグローバルメモリに依存する可能性があるため、2つのエミュレーターを同時に実行しようとすると、互いに干渉します。これが仮想化が解決するものであり、シミュレーションを分離します。

お役に立てば幸いです。

0
Lance Pollard