#navi_header|技術| "WindowsOS内部のアーキテクチャのすべて"の第5章~第6章の要約、読書メモとなります。 本記事では以降、"WindowsOS内部のアーキテクチャのすべて" を "Windows OS Internal Architecture" として "WOIA" と略します。 #amazon||> ||< #more|| #outline|| ---- * (5章) Intel 80386 (32bit時代, 1985 - ) と Windows 3.x/9x 時代 1985年、アドレスバスや汎用レジスタ・内部/外部データバスが32bit化された80386が発表される。386で導入されたページング機構により、搭載された物理RAMメモリを超えた4GBメモリ空間にアクセス可能となった。同じく386で導入された仮想86モードにより、8086/8088時代のDOSアプリケーションを実行することもできるようになった。 ** Intel 80386 80386のスペック: | アドレスバス | 32bit | | 汎用レジスタ | 32bit(一部16bit) | | 外部データバス | 32bit | | 内部データバス | 32bit | 汎用レジスタについては殆どが32bit化されたが、後述するように一部16bitのままとなった。外部データバスについては、Pentium以降は64bitに増えている。 新機能: : ページング機構 : プロテクトモードでのセグメント方式で算出されたアドレスを、任意の物理メモリにマッピングする仕組み。マッピングするのが4KBサイズの「ページ」単位で行われる。386以降では一つのセグメントサイズが最大4GBに拡張されたが、実際のアプリケーションは4GB全てを使うわけではない。ページング機構を使うことで、4GBのうち実際に使用するメモリだけを物理メモリに配置することができる。物理RAMが4GBに満たない状態でも、これにより個々のアプリケーションに仮想的な4GBフラットメモリ空間を提供することができる。 : 仮想86モード : 386のマルチタスクでは、タスク単位で仮想的な8086環境を提供することができるようになった。これにより、他のアプリやOSから分離された安全なMS-DOS実行環境(MS-DOSプロンプト)が使えるようになった。 ページング機構: 80286:セグメント+オフセット = 物理メモリアドレス 80386:セグメント+オフセット → ページング機構による変換 → 物理メモリアドレス ページング機構や仮想86モードの詳細は本記事の範疇を超えるので割愛する。 *** レジスタ構成 汎用レジスタ(32bit): EAX, EBX, ECX, EDX, EBP, ESP, ESI, EDI →それぞれ下位16bitを AX, BX, CX, DX, BP, SP, SI, DI でアクセス可能 セグメントレジスタ(16bit):FSとGSが追加 CS, SS, DS, ES, FS, GS ステータスとInstruction Pointer(32bit): EFLAGS, EIP (それぞれ下位16bitでアクセス可能) コントロールレジスタ(32bit): CR0 - CR3 80286のMSWはCR0になった。 セグメントレジスタは16bitのままだが、これはプロテクトモードでは「セレクタ」として使われるため、bit幅としては充分な幅を持つ。 オフセットとして使われる汎用レジスタ、EIPが32bit化されたことにより、32bit = 4GBまでのオフセット指定が可能になった。 ** 386以降での Windows 3.x, Windows 9x の起動 Windows 3.x "386 Enhanced Mode"(エンハンスモード)の起動: + MS-DOS起動(リアルモード) + AUTOEXEC.BAT or ユーザー入力で WIN.COM 起動(リアルモード) + WIN.COM から WIN386.EXE 起動(リアルモード → プロテクトモード) + WIN386.EXEが4GBフラットメモリ空間を確保 Windows 9xでは、WIN386.EXEが"VMM32.VXD"という"仮想マシンマネージャ"に取って代わる。 + MS-DOS起動(リアルモード) + 自動的に WIN.COM 起動(リアルモード) + WIN.COM から VMM32.VXD 起動(リアルモード → プロテクトモード) + VMM32.VXDが4GBフラットメモリ空間を確保 ** "仮想マシン"マネージャ 386以降のCPUでは、マルチタスクとページング機構を使って、アプリケーションそれぞれに仮想のCPU、仮想のメモリ空間を割り当てられる。仮想のCPUについては286以降導入されたマルチタスク機能で実現され、仮想のメモリ空間については386以降のページング機構で実現出来る。 物理的に一つのCPU/メモリ上で複数のアプリを同時に実行し、それぞれのアプリケーションから見れば自分専用のマシンで実行されているように見えるようになった。Windows 3.x エンハンスモードおよびWindows 9xでは、これら仮想的なCPU/メモリの組み合わせを「仮想マシン」としてセットで扱うようになった。 この仮想マシンを管理するのが仮想マシンマネージャであり、Windows 3.x エンハンスモードなら "WIN386.EXE", Windows 9xなら "VMM32.VXD" がその役目を担う。 Windows 3.x/9xでは、OSやWindowsアプリケーションを動かす為の仮想マシンが最初に1台作成される(システムVM)。以降、MS-DOSプロンプトを使って、仮想86モードによりMS-DOS用の仮想マシンが作成される。 Windows 3.x/9xの段階では、Windowsアプリケーションそれぞれに対して専用の仮想マシンは作成されない。一つのシステムVMの中で、OSコンポーネントとWindowsユーザーアプリケーションが同居する形になる。 ** Windows 3.x エンハンスモードの特徴 + 複数のWin16アプリケーションが同じメモリ空間に存在する。 + 複数のWin16アプリケーション間は協調型(ノンプリエンプティブ)マルチタスク。 + Windows NT と同じ仕様にする為、4MB - 2GBまでは空き領域(予約)。 #pre||> +----------------------------------+ 4GB | Windows 3.xシステム領域 |<-- RING-0 | (仮想マシンマネージャ, | | 各種仮想デバイスドライバ(VXD), | | 他) | +----------------------------------+ 3GB | Win16アプリケーション領域, | | +----------------------------| | | Win16 App 1 |<-- RING-3 | +----------------------------| | | | +----------------------------| | | Win16 App 2 | | +----------------------------| | | | +----------------------------| | | Win16 App 3 | | +----------------------------| | | +----------------------------------+ 2GB | | | 空き領域 | | | +----------------------------------+ 4MB | 未使用領域 | +----------------------------------+ 1MB | Win16API | +----------------------------------+ | MS-DOSシステム | +----------------------------------+ 0 ||< ** Windows 9x の特徴 + Windows NT から受け継いだ "Win32 API" を利用出来る。 + Win32アプリケーション領域については、アプリケーション毎に固有のメモリ空間を持つことが出来る。 + Win32アプリケーションについては、プリエンプティブマルチタスクに対応。 + Win16アプリケーションについては、2GB - 3GBの間を複数アプリケーションで共有する。 Windows 9x 起動完了時のメモリ空間: #pre||> +----------------------------------+ 4GB | Windows 9xシステム領域 | | (仮想マシンマネージャ, |<-- RING-0 | 各種仮想デバイスドライバ(VXD), | ... 各 4MB - 2GBメモリ空間(RING-3) | Win32API) | +--------------+ +----------------------------------+ 3GB | Win32 App 3 | | Win16アプリケーション領域, | +--------------+ | | Win32アプリケーション共有メモリ | | Win32 App 2 | | +----------------------------------+ 2GB +--------------+ |-+ | | | Win32 App 1 | | | Win32アプリケーション領域 |<--------| |-+ | | | | +----------------------------------+ 4MB +--------------+ | 未使用領域 | +----------------------------------+ 1MB | Win16API | +----------------------------------+ | MS-DOSシステム | +----------------------------------+ 0 ||< ** Win16 API, Win32 API の共存について | Win16 API | Win32 API |H | KRNL386.EXE | KERNEL32.DLL | | USER.EXE | USER32.DLL | | GDI.EXE/他 | GDI32.DLL/他 | Win16/Win32 APIの共存方法とは、"サンクレイヤ"という変換レイヤーを使ってWin16/Win32の呼び出しを変換する方式: [Win 16] KERNEL386.EXE の呼び出し → サンクレイヤ → KERNEL32.DLL USER.EXE, GDI.EXEの呼び出し → そのまま [Win 32] KERNEL32.DLL の呼び出し → そのまま USER32.DLL, GDI32.DLL/他の呼び出し → サンクレイヤ → USER.EXE, GDI.EXE/他 このようにKERNEL機能は Win32 の KERNEL32.DLL の処理に統一されたが、USER/GDI機能は逆に Win16 の USER.EXE/GDI.EXE に統一されてしまった。USER.EXE/GDI.EXEは、1セグメント64KBの制限が前提で開発されている。その上、複数のアプリケーションとシステムコンポーネントのメモリ空間が同じであるため、複数のWin16/Win32アプリの要求を、一つの64KBセグメントの中で処理する必要がある。 このため、Windows 9x 時代でもリソース不足の問題は頻発した。 この共存はマルチタスクにも影響を及ぼしている。Win32はNTカーネルを出自としているため、OSが強制的に実行権を取りあげるプリエンプティブマルチタスクに対応している。一方、Win16は協調型(ノンプリエンプティブ)マルチタスクとなっている。 このため、Win16のUSER.EXE/GDI.EXEをプリエンプティブマルチタスクに対応させる必要があった。そのために"Win16Mutex"という排他制御が組み込まれ、複数のWin32アプリケーションがUSER32.DLL/GDI32.DLLを呼んだ場合、サンクレイヤの中で"Win16Mutex"により排他処理が行われてUSER.EXE/GDI.EXEを呼び出す機構になっている。 ざっくりまとめると、Win32/Win16の共存によるシステムの不安定さがWindows9xの弱点だった。 * (6章) Windows XP Windows XP、総じて Windows 2000 以降のWindowsNTベースのシステムアーキテクチャについては、極簡単にまとめておく。 + MS-DOSが不要になった。 ++ OSブート時はMS-DOSからではなく、NTLDRがリアルモード→プロテクトモードへの切り替えとシステムロードを実行する。 + OSコンポーネントとアプリケーションの分離が進んだ。 ++ カーネル(NT Executive)とアプリケーションは"Local Procedure Call"(LPC)を使って通信するようになった。 + アプリケーション毎に仮想マシンが与えられるようになった。 ++ アプリケーションのメモリ空間から見えるWin32は、スタブDLLとなりNT ExecutiveにLPC通信するフロントエンドのような位置づけになった。 ++ OSコンポーネントが動作するシステムVMとの通信もNT Executiveが仲介するようになった。 + "Hardware Abstraction Layer"(HAL)の導入により、CPU依存とそうでないコードの分離が進んだ。 Windows NTでは OS/2 や UNIX 用のインターフェイスを提供出来る仕組みになっている。「サブシステム」と呼ばれるレイヤーがそれであり、Win32 APIは「Win32 サブシステム」とも呼ばれる。 サブシステムが、OS/2,UNIX,WindowsそれぞれのOS機能呼び出しをNTカーネルに変換し、NT ExecutiveにLPC通信する仕組みになっている。 重要な点は、OSコンポーネントとアプリケーションのメモリ空間が、仮想マシンのレベルで分離された点である。これによりアプリケーションがどんなにそのメモリ空間を破壊したとしても、OSコンポーネントは別の仮想マシン(=別のメモリ空間)に分離されている為影響しない。 アプリケーション空間に存在するWin32APIのコードはLPC通信を行うスタブDLLであり、同時に他のアプリケーションのメモリ空間とも分離されている(DLLのコピーが存在するのみ)。つまり誤ってアプリケーション空間のWin32領域を破壊したとしても、他のアプリケーションには影響しない。 ** Windows XP上のDOSアプリケーション Windows XPではMS-DOSを用いない。そのため、MS-DOSアプリケーションを動かす為には"NTVDM.EXE"が仮想86モードを使ってMS-DOS環境をエミュレートする。 #pre||> +--------------------------------+ 0 | 16bit MS-DOS エミュレーション |------------+ | (NTVDM.EXE) |<-------+ | +--------------------------------+ (1)| |(2) | MS-DOSアプリケーション |--------+ | +--------------------------------+ 640KB | | | | +--------------------------------+ 1MB | [16bit] ==============================================|=========== +--------------------------------+ | [32bit] | 32bit MS-DOS エミュレーション |<-----------+ | (NTVDM.EXE) |-----+ +--------------------------------+ | |(3) +--------------------------------+ | | Win32サブシステム |<----+ +--------------------------------+ |(LPC) V NT Executive ||< ** Windows XP上のWin16APIアプリケーション Win16 APIを使ったアプリケーションを実行する場合は、"Win16 On Win32"(WOW, WOWEXEC.EXE)という仕組みによりWin16環境をエミュレートする。NTDVM.EXEによるMS-DOS環境の上に、さらにWin16エミュレート環境を被せる形になる。 #pre||> +--------------------------------+ 0 | 16bit MS-DOS エミュレーション | | (NTVDM.EXE) | +--------------------------------+ | Win16APIのスタブ |------------+ | |<-------+ | +--------------------------------+ 640KB | | | | | | +--------------------------------+ 1MB | | | | | | | +------------------------------| (1) | | (2) | | Win16 Application 1 |--------+ | | +------------------------------| | | | | | +------------------------------| | | | Win16 Application 2 | | | +------------------------------| | | | | | +------------------------------| | | | Win16 Application N | | | +------------------------------| | | | | +--------------------------------+ 16MB | [16bit] ==============================================|=========== +--------------------------------+ | [32bit] | Win16 → Win32 |<-----------+ | エミュレーション |-----+ +--------------------------------+ | | +--------------------------------+ | | 32bit MS-DOS エミュレーション | | | (NTVDM.EXE) | | +--------------------------------+ | |(3) +--------------------------------+ | | Win32サブシステム |<----+ +--------------------------------+ |(LPC) V NT Executive ||< Windows NT 4.0 では、個々のWin16アプリケーション毎にそれぞれ専用の仮想マシンを提供することができた。「ファイル名を指定して実行」を起動する時に「別メモリ領域で実行する」チェックボックスをオンにするのがそれにあたる。 Windows XP 以降ではそのようなオプションが見当たらないことから、WOIAではWindows XPにおいては一つの仮想マシン中で複数のWin16アプリケーションを協調型マルチタスクで動作させているのではないか、と推測している。 ** Windows XP以降のまとめ + MS-DOSを使わない、32bitを前提としたNTカーネル。 + OSコンポーネントとアプリケーションのメモリ空間を分離し、やりとりはLPC(Local Procedure Call)を使うように整理。 + アプリケーション毎に仮想マシンを用意することで、完全なプリエンプティブマルチタスクを実現。 + MS-DOS, Win16APIアプリケーションを動作させる場合は仮想86モードを使った仮想マシン内に閉じこめ、MS-DOSやWin16APIをエミュレーションするレイヤーを用意してWin32サブシステムと通信する。 これらの特徴により安定したOS環境が実現している。 #navi_footer|技術|