WSL2上のLinuxでUSBストレージデバイスを使う
WSLでUSBメモリとかを使いたい
いつ頃かは知りませんが,OSSのusbipd-winを利用して,WSL2上のLinuxにUSBデバイスを共有できるようになってたみたいですね.
Windows11のWSL標準Linuxカーネルには,既にUSBIPのモジュールが組み込まれているみたいです.なので単に接続するだけであれば,USBIPホストとクライアントの設定だけで利用できます.ただ,USB Mass Storage Driverが標準カーネルに組み込まれていないので,ストレージデバイスとして使いたい場合は独自にビルドしたカーネルを使用する必要があります.
Windows10の場合はUSBIPのモジュールもデフォルトで組み込まれていないようなので,これも独自にビルドする必要があるようですね.
備忘録がてら手順を残しておきます.(少し癖のある環境なのでアテにならないかもしれない…)
あとZennで物書くのは初めてなんでお手柔らかに…
(特に断りがない場合,表記しているコマンド類はWSL or Linux環境で実行するものです)
使用環境
- Windows 11 Pro 22H2 (x64)
- WSL (Version
1.0.0, MS Store版)- Distribution: Arch Linux (ArchWSL
22.10.16.0, WSL2) - Kernel:
5.15.74.2-microsoft-standard-WSL2
- Distribution: Arch Linux (ArchWSL
要件
基本はMicrosoftのドキュメントの要件を満たしていればOKです.
Linuxカーネルのビルドをするので,ある程度リソースに余裕のあるWSLか普通のLinux環境があると望ましいです.ここでは既存のWSL上でそのままビルドします.
Linuxカーネルのビルド・変更
依存パッケージの導入
カーネルビルドに必要なパッケージを調べて,先に導入しておきます.
Linuxの公式ドキュメントに最低限必要なプログラムのリストがありますが,<ディストリビューション名> kernel build requirementsとかでググれば,パッケージマネージャのコマンドごと出てくると思います.
Ubuntuの依存パッケージはWSL2カーネルのREADMEにありますね.
自分のArchLinux環境ではとりあえずこれで通りました.(pacmanラッパーのyayを使ってるので,適宜pacmanなりに読みかえてください)
yay -S base-devel asp pahole
足りないときはビルド時にエラーが出ますが,大抵どのプログラムがない等が出力されるので,それを見て対応すればOKです.
リポジトリのクローン
WSL2カーネルのリポジトリをクローンします.
git clone https://github.com/microsoft/WSL2-Linux-Kernel.git
トータルで3~4GBくらいあるんで,ストレージに余裕のない方は注意した方が良いです.
Build Configuration
いくつかやり方はありますが,ここではデフォルトのconfigをコピーしてきて,menuconfigで変更します.
- クローンしたディレクトリのルートで,以下を実行します.
cp ./Microsoft/config-wsl ./.config
make menuconfig
-
このようなTUIが出てきます.十字キーと
<Enter>で操作します.

menuconfig
Device Drivers→USB Supportと進み,USB Mass Storage supportを探します.

Device Drivers

USB Support

USB Mass Storage support
これを選択した状態で,Yを押します.すると項目左側のカッコに*が表示され,ドライバが有効になります.

こんな感じ
基本的にはこれでOKですが,別途特別なドライバが必要な場合はここで一緒に有効にしておきます.心当たりがなければ,このままで問題無いです. -
変更したConfigを保存します.左右キーで下側のコマンドのカーソル(画像参照)を動かし,
Saveを選んでEnterを押します.

Save
保存するファイル名を聞かれますが,特に変更の必要もないのでそのままEnterでOKです.
Optional: Local versionの変更
General Setup → Local version から,Local version名の変更が可能です.uname -aとかで確認したときに出てくるやつですね.
そのままでも問題無いですが,オリジナルと区別できるように適当に変えておくと良いでしょう.
デフォルトは-microsoft-standard-WSL2です.

Local version
- 同様に
Exitを選択して終了します.
ビルド
以下のコマンドでビルドします.
make -j $(nproc)
何回もカーネルのビルドを経験してると最早気になりませんが,貧弱なCPUだと結構時間がかかります(特にラップトップとかはクロックでないので…).筆者のデスクトップで4分程度,ラップトップでは十数分かかりました.
-jオプションを付けないと単一ジョブで走るので,更に遅くなります.
参考までにビルドした環境も載せときます.WSLで利用できるリソースに制限をかけているので,フルパワーの時より劣る結果にはなっています.
ビルド環境
- デスクトップ
- CPU: Intel Core i7-12700K 12C/20T 8コア制限
- RAM: DDR5-5200 64GB 16GB制限
- ラップトップ
- CPU: Intel Core i7-8750H 6C/12T 6コア制限
- RAM: DDR4-2666 16GB 8GB制限
特に設定をいじっていなければ,CPUは搭載の全コア,メモリは全体の80%上限だったと思います.
完成したカーネルは,vmlinuxという名前でディレクトリのルートにいます.
❯ ls -lh vmlinux
-rwxr-xr-x 1 nanami nanami 808M Nov 28 01:39 vmlinux
ちなみに,ビルド後はArtifactで +4GB 程度ストレージを圧迫するので注意してください.
❯ du -sh
7.1G .
カスタムカーネルに変更
.wslconfigで作成したカーネルを指定し,WSLで使われるカーネルを差し替えます.この操作はWSLの全ディストリビューションに対して有効です.
-
vmlinuxをWindows側のファイルシステムへコピー
置き場所はWindows側のファイルシステム上であればどこでも良いです.
わかりやすい場所が良いので,Cドライブ直下などにディレクトリを作るのがベターでしょう.
併せて適当にリネームもしています.
mkdir -p /mnt/c/wsl
cp ./vmlinux /mnt/c/wsl/515-microsoft-nanamiiiii-WSL
-
(作成していない場合)
%USERPROFILE%直下に.wslconfigファイルを作成する
%USERPROFILE%はユーザーディレクトリ,つまりC:\Users\username直下のことです.

.wslconfig -
.wslconfigにカーネルの設定を書き込む
.wslconfigはini形式の設定ファイルで,全WSL環境で共通の設定になります.
ここでkernelに先ほどコピーしたvmlinuxへのパスを指定します.
\はエスケープをしないと正しく解釈されません
[wsl2]
kernel=C:\\wsl\\515-microsoft-nanamiiiii-WSL
WSLを再起動
以下はPowershell等Windows側のシェルから実行してください.
筆者はNushellを使用しています.
wsl --shutdown
wsl
これで正常にWSLが立ち上がれば完了です.uname -aでVersion Stringを確認すると,変化していることが分かります.

uname -a
usbipd-winのインストール
上のリポジトリのReleaseより,最新のmsiをダウンロード・インストールします.
wingetでもインストールできます.
winget install --interactive --exact dorssel.usbipd-win
PATHを反映するため,ここで再起動しておくと良いでしょう.
LinuxにUSBIPクライアントをインストール
ここもディストリビューションによって異なるので,自身の環境にあった導入をしてください.
Ubuntuの場合はMicrosoft公式Docsに記載があります.
筆者環境(ArchLinux)の場合は以下でOKです.
yay -S usbip
USBストレージを接続
WSLのシェルを開いた状態で,別に管理者権限のPowershell (or その他Windowsのシェル) も立ち上げておきます.
Tips: Windowsのsudo
WindowsでもLinuxのsudoのように,一般ユーザーから管理者権限へ昇格してコマンド実行ができる方法が存在します.
Powershellスクリプトでゴニョゴニョしたり,外部ツールを入れたりなどいくつかありますが,以下の記事の方法が一番簡単でしょう.
これを導入すると,sudo <command>を打つことでUACダイアログが現れ,管理者権限でコマンドを実行できます.
- Windowsのシェルから,接続可能なUSBデバイスをリストアップします
usbipd wsl list

usbpid wsl list
ただここではUSB Mass Storage Deviceとしか表示されないので,接続したいデバイスが特定できない場合があります.そのときは,USBデバイスのプロパティへ飛び,ParentのVID:PIDとシェルに現れたVID:PIDを照合することで特定できます.

Device Properties
この画像の場合,VID:PIDが8564:1000のデバイスがParentにあたるので,BUSID:1-8のデバイスをWSLにアタッチします.
- BUSIDを指定してデバイスをWSLにアタッチ
オプション-bでBUSIDを指定します.
WSLにアタッチしている間,そのデバイスにはWindows側からアクセスできないので注意してください.
usbipd wsl attach -b 1-8

STATEがAttachedに変化
- WSL側で確認
lsblkやfdiskで,USBストレージが読み込まれていることを確認します.lsusbでは認識されているのにこれらのコマンドで現れない場合は,Mass Storage Driverが読み込まれていない可能性が高いです.

lsblk
ここからは,通常のLinuxの場合と同様に扱うことができます.個人的にはddでフラッシュメモリにイメージを焼くときに重宝してます.
作業が終わったら…
WSLからデタッチして,Windows側に戻します.同じく管理者権限のPowershellで以下を実行します.
usbipd wsl detach -b 1-8
# STATEがNot Attachedとなっているのを確認する
usbipd wsl list

Not Attachedに戻っている
おわりに
大したことをやっているわけではないですが,慣れない人からすれば面倒な点がいくらかあるかと思ったので,少し丁寧に書きました.
自分は組み込みデバイスのFWフラッシュやシリアルコンソール,JTAGデバッガなどをよく使うので,この機能は重宝しています.
間違いや指摘などあれば気軽に教えていただけると助かります.
Discussion