WSLのUbuntu22.04上でラズパイ4向けのLinuxイメージをYoctoを使ってビルドして、そのままUSBカードリーダで接続したSDカードにWSLから直接書き込もうと試みたのですが、ドライバが足りていなくてすんなりとはいかなかったので、そのときのメモです。
原因
WSLからホストに接続されているUSBデバイスにアクセスするためには、「USB デバイスを接続する」の指示に従って事前にデバイスをアタッチしておく必要があります。
しかし、上述の作業をするだけではSDカードがWSLからはデバイスが認識されませんでした。Windows側では下記のBUSID 4-1のようにSTATEがAttachedの状態になっていることを確認できたのですが、WSL側だとlsblk
コマンドなどで確認してもデバイスが認識できませんでした。
PS C:\Users\ken> usbipd attach -b 4-1 --wsl
usbipd: info: Using WSL distribution 'Ubuntu-22.04' to attach; the device will be available in all WSL 2 distributions.
usbipd: info: Using IP address 192.168.112.1 to reach the host.
PS C:\Users\ken> usbipd list
Connected:
BUSID VID:PID DEVICE STATE
1-1 04fe:0022 USB 入力デバイス Not shared
1-2 0b05:19af AURA LED Controller, USB 入力デバイス Not shared
1-9 046d:c52b Logitech USB Input Device, USB 入力デバイス Not shared
1-10 046d:c53f LIGHTSPEED Receiver, USB 入力デバイス Not shared
2-3 10d7:b012 Generic Bluetooth Adapter Not shared
4-1 14cd:1212 USB 大容量記憶装置 Attached
4-2 25a4:9311 USB C Video Adaptor Shared
この原因は、USBのストレージデバイスを認識するために必要がドライバがUbuntu22.04のWSLカーネルに含まれていないことにありました。
USBのストレージデバイスを使用するためには、カーネルモジュールのusb-storage.koが必要です。しかし、/lib/modules
を確認したり、lsmod
コマンドを確認すればわかるように、WSLカーネルにはカーネルモジュールがデフォルトだと一切梱包されていません。デフォルトのWSLカーネルではすべてのドライバが静的にリンクされているようです。
だからといって、less config.gz | grep CONFIG_USB_STORAGE
コマンドで確認しますが、カーネルコンフィグ内にUSBのストレージデバイスを有効化するような記述も見当たりません。したがって、ドライバ自体がUbuntu22.04のWSLにそもそも入っていないことが本件の原因だと考えられました。
解決方法
解決方法として以下2つの方法が考えられます。
1. ドライバを含めたカスタムカーネルをビルドして使用する方法
カーネルコンフィグのUSB Mass Storage support
を有効化したうえでビルドし直したカーネルをWSLで使用するように変更する方法です。
手順は、https://myuu.dev/blogs/wsl-usb-storage あたりの記事が参考になりました。
ポイントは、configを有効化する際には、config間の依存関係があるので、そちらも合わせて有効化することです。例えば、USB Mass Storage support
をyするためには、USB Attached SCSI
あたりも合わせてyにしておく必要がありました。また、USBをWSLにアタッチする際にvhci_hcd failedが発生したため、合わせてVHCI hcd
もyにしておきました。
この方法で、SDカードをUSBストレージデバイスとして認識できるようになりました。
2. カーネルモジュールをビルドして動的にロードする方法
ドライバをカーネルモジュールとしてビルドして、modproveでロードする方法です。
モジュールはカーネルのバージョンごとにビルドする必要があるので、どのみちカスタムカーネルを作る必要がありそうです。デフォルトだとドライバがすべて静的にリンクされているところを見るに、WSLにおいてカーネルモジュールを動的にロードするのは作法がよろしくないのかもしれません。カーネルモジュール自体はサポートされているというところで、試してはいないですが、理論的には可能ではないかと思われます。
おわりに
デフォルトのWSLカーネルにドライバを含めておいてくれれば助かるのですが、セキュリティ等の都合でできないのかもしれないですね。カーネルやモジュールを自前で保守しないといけないデメリットはありますが、ラズパイ等をよく使用する場合は専用の開発環境としてもっておいてもいいかもしれないですね。
参考
- https://www.kernelconfig.io/config_usb_storage
- https://learn.microsoft.com/en-us/community/content/wsl-user-msft-kernel-v6
- https://myuu.dev/blogs/wsl-usb-storage
- https://scrapbox.io/saitotetsuya/WSL2%E3%81%ABUSB%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%82%92%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B#6506a2e2021fd8000081ab7a