WSLとWindowsのLinux互換レイヤの仕組み
WSL1がなぜ速いのに非互換が残り、WSL2がなぜ互換だがファイルが遅いのか。syscall変換と軽量VMの違いを内部から押さえれば、どちらを選ぶべきか自分で判断できるようになります。
- 1.WSL1はLinuxのsyscallをWindowsカーネルのpicoプロセスでNTネイティブ操作へ変換する互換レイヤで、VMを持たないため起動が速くWindowsファイルへの相互アクセスも軽いが、未実装syscallや挙動差で互換性に穴が残る。
- 2.WSL2は軽量Hyper-V VMで本物のLinuxカーネルを動かすため互換性は完全に近いが、クロスOSのファイル共有が9P(新しめのWSLでは一部virtio-fs)プロトコル越しになり、ファイルI/Oが遅くなる。
- 3.性能の勘所は「ファイルがどちら側に置かれるか」。Linuxネイティブ作業はWSL2が圧倒的に速く、WindowsとLinuxを頻繁に跨ぐ軽量作業はWSL1が有利、という非対称なトレードオフになる。
互換レイヤには2つの根本的に違う設計がある
WSL(Windows Subsystem for Linux)は、Windows上でLinuxのバイナリをそのまま動かす仕組みです。重要なのは、WSL1とWSL2が名前こそ似ているが、設計思想がまったく異なる ことです。WSL1は「LinuxのsyscallをWindowsカーネルが翻訳する互換レイヤ」、WSL2は「軽量VMの中で本物のLinuxカーネルを動かす仮想マシン方式」です。前者はカーネルを共有し、後者はカーネルを分けます。この一点が、互換性・性能・ファイル共有のすべての違いを生みます。
両者の系譜は OS仮想化技術の系統 に位置づけられます。WSL1はカーネルを共有する点でコンテナに近く、WSL2は専用カーネルを持つ点で軽量VMそのものです。
WSL1:picoプロセスとsyscall変換レイヤ
WSL1の核心は picoプロセス という機構です。Windowsカーネルには、通常のNTプロセスとは別に、最小限の構造体だけを持つ「空っぽの」プロセス を作る仕組みがあり、そこに動作を注入するカーネルドライバ(pico provider)として lxcore.sys / lxss.sys が組み込まれます。Linuxのバイナリはこのpicoプロセス内で動き、ELFバイナリがそのまま実行されます(ELFローダの内部 で扱う形式のバイナリです)。
肝はsyscallの扱いです。Linuxプログラムが read や fork といったLinux ABIのsyscallを発行すると、CPUはカーネルへトラップしますが、その入口で pico providerがLinuxのsyscall番号と引数規約を解釈 します。そして対応するNTネイティブの操作へ翻訳します。たとえば次のような対応です。
| Linux syscall | WSL1の内部処理 | 対応するNTの世界 |
|---|---|---|
| open / read / write | VFS風の層を通しNTのファイルオブジェクトへ | NtCreateFile / NtReadFile |
| fork | 親アドレス空間を複製しpicoプロセスを生成 | NTにforkは無く独自実装で再現 |
| mmap | セクションオブジェクトとビューのマッピング | NtMapViewOfSection |
| ioctl など一部 | 未実装または部分実装 | 対応するAPIが無い場合は失敗 |
つまりWSL1は、Linux ABIをWindowsカーネルのNT APIへ写す 巨大な翻訳辞書 です。システムコールのABIと呼び出し機構 の知識がそのまま効く領域で、レジスタ規約・エラー番号・引数構造体をLinux流からNT流へ橋渡しします。
Linuxの fork は「親プロセスをまるごと複製し、コピーオンライトでアドレス空間を共有する」セマンティクスを持ちます。一方NTカーネルには fork 相当の基本操作が無く、プロセス生成は常に「新しいイメージをロードする」モデル(CreateProcess)です。WSL1はこのギャップを picoプロセスの複製として独自に実装しましたが、fork 後の状態を完全に再現するのは難しく、WSL1の互換性が完璧になりきれない代表的な原因のひとつになりました。
WSL1の利点は、VMが無いこと に尽きます。Linuxプロセスは普通のWindowsプロセスと同じスケジューラ上で動き、メモリも動的に共有されます。WindowsのファイルはNTFS上のファイルへ直接アクセスするため、C: ドライブ配下の読み書きが軽い。起動も一瞬です。弱点は 互換性の穴:未実装・部分実装のsyscall、/proc や /sys の差異、ネットワーク周りの挙動差などで、特定のソフトウェア(DockerデーモンやネイティブGUIなど)が動かないことがありました。
WSL2:軽量VMと本物のLinuxカーネル
WSL2はこの互換性問題を、発想を変えて解決します。翻訳をやめて、本物のLinuxカーネルをVMで動かす のです。Microsoftがビルド・配布する実カーネル(mainlineに近い構成)を、Hyper-Vベースの軽量VM上で起動します。これにより、syscallはLinuxカーネルがそのまま処理するので、互換性はネイティブLinuxにほぼ等しく なります。Dockerが動き、/proc も完全に揃います。
ここでの「軽量」がポイントです。WSL2は従来型の重いVMではなく、Hyper-Vの最小ハイパーバイザ機能の上に薄いVMを置き、起動を高速化するための仕掛け を多数持ちます。代表的なのが、Windowsのファイルから直接Linuxカーネルとして起動できる仕組みや、CPU・メモリをホストと動的にやり取りする機構です。この層は ハードウェア仮想化拡張(VT-x/AMD-V) の上に成り立っており、ゲストのLinuxは仮想CPU上で素のカーネルとして走ります。
I/Oは準仮想化で処理されます。ディスクやネットワークは virtioとパラ仮想化I/Oの仕組み を使い、ゲストとホストが共有リングでデータをやり取りすることで、エミュレーションのオーバーヘッドを避けます。WSL2のファイル共有もこの延長線上にあります。
WSL2のVMは必要に応じてメモリを確保しますが、一度Linux側が確保したページをWindowsへ返すのは遅れがち です。Linuxカーネルはページキャッシュにメモリを抱え込む性質があるため、大きなビルドのあとWSL2が物理メモリを握ったままになることがあります。新しいWSLはこれを緩和する自動再利用機構を持ちますが、原理上WSL1の「同じカーネルでメモリ共有」ほど素直ではありません。
ファイル共有:9PとvirtiofsとDrvFs
設計の違いが最も体感に出るのが クロスOSのファイルアクセス です。WSL2はカーネルが分かれているため、片方のOSのファイルへもう片方からアクセスするには、ネットワーク/IPC越しのファイルプロトコルが必要になります。
- Linux側からWindowsファイル(
/mnt/c)へ:当初は 9P(Plan 9 Filesystem Protocol) が使われました。9Pは1リクエスト=1往復のシンプルなプロトコルで、Linux内では VFS(仮想ファイルシステム)層 のファイルシステムとしてマウントされ、各open/read/statがWindows側のサーバーへメッセージとして飛びます。実装は素直ですが、メタデータ操作のたびに往復が発生 するため、大量の小さいファイルを扱うと遅くなります。 - Windows側からLinuxファイル(
\\wsl$や\\wsl.localhost)へ:同じく9Pサーバーを介します。VM内のLinuxファイルシステムへ、Windowsのエクスプローラやエディタからアクセスできます。 - virtio-fs への移行:新しいWSLは性能改善のため virtio-fs を採用しつつあります。virtio-fsはvirtioの共有メモリ機構を使い、DAX的な共有でホストのページキャッシュをゲストへ見せられるため、9Pより往復とコピーを大幅に減らせます。
対してWSL1は、Windowsファイルを DrvFs という変換ファイルシステムでマウントし、カーネル内で直接NTFSのファイルオブジェクトへ橋渡し します。プロトコルの往復が無いため、/mnt/c 配下の操作はWSL2の9P経由より軽くなります。
| 観点 | WSL1 | WSL2 |
|---|---|---|
| カーネル | Windows NTカーネルを共有(翻訳) | 本物のLinuxカーネルを軽量VMで実行 |
| 互換性 | syscall翻訳ゆえ穴が残る | ネイティブLinuxにほぼ等しい |
| Linuxネイティブ FS I/O | ext4風だがNT越しでやや不利 | VM内ext4で非常に高速 |
| WindowsファイルへのI/O | DrvFsで直接、軽い | 9P/virtio-fs越しで遅い |
| 起動・メモリ | 即起動・メモリ共有 | VM起動・メモリ回収がやや遅い |
| Docker等の重い機能 | 動かないものがある | 問題なく動く |
相互運用と性能の判断軸
WSLが便利なのは、Linux側からWindowsの実行ファイルを、Windows側からLinuxコマンドを、互いに呼べる 相互運用です。WSL1では同一カーネル内のプロセス間連携として、WSL2では init がホストとパイプで繋がる仕組みとして実現され、notepad.exe をLinuxシェルから起動したり、wsl ls をPowerShellから叩いたりできます。ネットワークも、WSL2は標準でNAT、設定により「ミラーモード」でホストとIPを共有でき、localhost の見え方が変わります。
性能の最終的な判断軸はシンプルです。ファイルをどちら側のファイルシステムに置くか で速さが決まります。
原則はWSL2で、ソースコードやリポジトリは 必ずLinux側(~ 配下のext4)に置く。これでビルドやgit操作がネイティブLinuxとほぼ同等になります。逆に /mnt/c 上で大量ファイルのビルドをすると、9P往復で劇的に遅くなるので避ける。WindowsとLinuxを跨ぐ軽量な作業が主体で、Docker等の重い機能が不要なら、WSL1の相互アクセスの軽さと即起動が有利な場面もあります。
「WSL1とWSL2の違いを一言で」と問われたら、WSL1はsyscall変換の互換レイヤ(カーネル共有・VMなし)、WSL2は軽量Hyper-V VM上の本物のLinuxカーネル(カーネル分離) と答える。互換性はWSL2が上、Windowsファイルへのアクセスの軽さはWSL1が上、という非対称を押さえる。ファイル共有は「Linux→Windowsが9P/virtio-fs、WSL1はDrvFsで直接」。性能の鉄則は「ファイルを置く側で速度が決まる」。picoプロセス・virtio・VT-xという3つのキーワードを結びつけられれば十分です。
まとめ
WSLの2世代は、互換と性能のトレードを真逆の設計で解いた 対照例です。WSL1は picoプロセス上でLinux syscallをNT APIへ翻訳する互換レイヤで、VMが無いぶん起動が速くWindowsファイルへのアクセスも軽い一方、fork などの再現が難しく互換性に穴が残ります。WSL2は ハードウェア仮想化拡張 の上の軽量VMで本物のLinuxカーネルを動かし、互換性をほぼ完全にした代わりに、クロスOSのファイルアクセスが virtio ベースの9P/virtio-fs越しになって遅くなります。だから実務の鉄則は「ファイルを置く側で速度が決まる」——Linux作業はLinux側のext4へ、これだけ守ればWSL2の互換性と速度を両取りできます。
OS Article
WSLとWindowsのLinux互換レイヤの仕組みを実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
WSL
比較で見る軸
難易度: advanced / カテゴリ: OS / タグ数: 6
導入後に効く点
WSL2は軽量Hyper-V VMで本物のLinuxカーネルを動かすため互換性は完全に近いが、クロスOSのファイル共有が9P(新しめのWSLでは一部virtio-fs)プロトコル越しになり、ファイルI/Oが遅くなる。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- OS
- タグ数
- 6
判断チェックリスト
- 自社の用途が「WSL / Windows」に近いか確認する。
- 強みである「WSL1はLinuxのsyscallをWindowsカーネルのpicoプロセスでNTネイティブ操作へ変換する互換レイヤで、VMを持たないため起動が速くWindowsファイルへの相互アクセスも軽いが、未実装syscallや挙動差で互換性に穴が残る。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。