在WSL上挂载U盘

记录一下在WSL上成功挂载U盘的过程。

1. 连接USB设备

按照官方文档,安装usbipd-win,即可从WSL访问USB设备。

正常使用的大致流程如下:

graph LR
A(共享) --> B(连接) --> C(挂载) --> | 使用 |D(卸载) --> E(断开连接) --> F(解除共享)

查看可用的USB设备:

1
usbipd.exe list

示例输出:

1
2
3
Connected:
BUSID VID:PID DEVICE STATE
2-3 0781:55ab USB 大容量存储设备 Not shared

使用BUSID指定要共享的USB设备(需要管理员权限):

1
sudo.exe usbipd.exe bind --busid 2-3

然后连接该设备:

1
usbipd.exe attach --wsl --busid 2-3

这时使用 lsusb 可以看到USB设备已经识别到了:

1
Bus 002 Device 003: ID 0781:55ab SanDisk Corp. Dual Drive

但是使用 lsblk 看不到该设备。原因是WSL的内核使用 CONFIG_USB_STORAGE=m 编译,需要手动加载对应的模块:

1
modprobe usb-storage

这时再运行 lsblk 就能看到新的设备了:

1
2
sde      8:64   1 114.6G  0 disk
└─sde1 8:65 1 114.6G 0 part

2. 挂载USB设备

如果U盘是FAT格式,这个时候就可以直接挂载了。

但是由于我的U盘比较大,之前格式成了exFAT格式。而WSL的内核没有编译exFAT(以及NTFS)的支持,因此要挂载U盘的话,需要重新编译内核。

不过编译内核也很简单,从官方内核仓库下载最新的内核,解压后进入文件夹,运行

1
2
cp Microsoft/config-wsl .config
make menuconfig

进入图形化配置界面,选择

1
2
3
4
5
File systems  --->
DOS/FAT/NT Filesystems --->
<M> exFAT filesystem support
<M> NTFS Read-Write file system support
<*> activate support of external compressions lzx/xpress

我直接把exFAT和NTFS的支持都加上了。

然后编译内核:

1
make -j$(nproc)

安装模块:

1
make INSTALL_MOD_PATH="$PWD/modules" modules_install

最新的WSL使用vhdx挂载modules:

1
sudo ./Microsoft/scripts/gen_modules_vhdx.sh "$PWD/modules" $(make -s kernelrelease) modules.vhdx

然后把内核映像 arch/x86/boot/bzImage 和内核模块 modules.vhdx 放到Windows的硬盘上(我放在了 D:\Temp)。

.wslconfig 中配置自定义内核:

1
2
3
[wsl2]
kernel=D:\\Temp\\bzImage
kernelModules=D:\\Temp\\modules.vhdx

然后重启WSL即可。

要挂载exFAT的U盘,还需要安装对应的软件:

1
emerge --ask sys-fs/exfatprogs

(如果是挂载NTFS格式的设备,需要则安装 sys-fs/ntfs3g。)

加载所需的内核模块:

1
modprobe usb-storage exfat

然后就可以正常挂载U盘了:

1
mount /dev/sde1 /media

使用完了之后断开连接并解除共享:

1
2
usbipd.exe detach --busid 2-3
sudo.exe usbipd.exe unbind --busid 2-3