准备在WSL2上继续搞点事情,可是当我在WSL内的Linux操作系统上连接USB存储设备时却出现了问题。本文是我解决这个问题的简单记录,以备后查,如果能够帮助到您,那更是我莫大的荣幸。
我的环境。
win11 必须在系统功能中开启“虚拟平台”可选功能,以及在计算机BIOS中需要开启虚拟化功能。
在win11中安装WSL ubuntu非常的简单,首先以管理员模式打开一个powershell,使用以下命令查看当前的WSL Linux 发行版本。
wsl --list --online
使用以下命令安装指定的发行版本。
wsl --install -d Ubuntu-20.04
由于我的系统已经安装过了,当时忘记截图,在此就不上图了。
同时还可以使用Microsoft Store
来安装WSL Linux。首先打开Microsoft Store
,在搜索应用中直接输入WSL,就会出现相应的WSL发行版本了。
点击发行版本右上角的免费下载就可以安装了。
💁?♂ WSL linux会默认安装到“C:\Program Files\WindowsApps”目录下,要确保你的C盘有足够的空间,同时你的C盘不能是压缩的。否则会造成WSL Linux无法运行。
💁 Microsofte Store经常会出现无法打开的现象,大家可以在Microsoft Store
的设置中修复、重置应用,然后再重置你的网络连接后重启电脑,再次打开Store就应该可以了。
要想实现windows和WSL通过USB进行通讯,首先需要在windows电脑上安装usbipd-win
驱动,在windows操作系统中,以管理员模式运行一个命令行窗口,并执行下面的命令。
winget install usbipd
只要您的系统能够正常连接互联网,上述命令会自动下载并安装usbipd-win
驱动,只要安装没有报错就是安装成功了。在进行后面的操作之前,大家最好先熟悉一下usbipd
的相关命令,通过usbipd --help
可以查看相关的帮助。
# 查看帮助
usbipd --help
其中比较常用的主要命令有以下命令。
# 列出连接到此windows的usb设备
usbipd list
使用以下命令,在windows中为指定槽位的USB设备绑定驱动程序。
usbipd bind -b 4-6
USB设备要连接到WSL,首先要开启WSL,以管理员身份打开一个powershell,在命令行中输入wsl
就能打开本机安装的WSL。
使用下面的命令将USB设备附加到WSL Linux上。
usbipd attach --wsl -b 4-6
💁?♂ WSL 1 和WSL 2的命令有稍微的区别。
上述命令执行完成后,如无报错在WSL中就应该能够查看到USB设备了。
上图所示,我连接了我的一个Kingston 的U盘。
断开USB连接只需要在windows中的powershell中执行以下命令就可以了。
usbipd unbind -b 4-6
断开连接后,在WSL中查看USB设备已经不存在了。
通过前面的操作,我们已经能够将USB设备连接到WSL Ubuntu中了,但是却无法读取U盘中的内容,显然这种连接是没有意义的,造成无法读写USB存储设备的主要原因是WSL Ubuntu发行版内核中缺少相应的USB设备的驱动程序。
因此只要找到对应发行版本的内核,重新编译内核将USB驱动添加进去就可以了。
在WSL Linux中执行下面的命令,安装编译内核所需的依赖。
sudo apt install build-essential flex bison libssl-dev libelf-dev libncurses-dev autoconf libudev-dev libtool
WSL2-Linux-Kernel
源码并切换分支从github上拉取WSL2-Linux-Kernel
源码包,源码包当前分支默认内核版本和最新的Linux内核相同,和我们通过WSL命令安装的Ubuntu2004并不是相同的内核版本,因此在编译内核之前要将WSL2-Linux-Kernel
切换到与当前WS Lubuntu2004系统内核版本相同的分支上来。
git clone https://github.com/microsoft/WSL2-Linux-Kernel.git
cd WSL2-Linux-Kernel
git checkout linux-msft-wsl-$(uname -r | cut -d- -f1)
修改WSL2-Linux-Kernel
内核配置,在WSL2-Linux-Kernel
内核中已经包含USB驱动,不过默认内核配置并没有自动加载USB存储驱动模块。接下来我们要修改WSL2-Linux-Kernel
默认内核配置,让它自动加载USB存储模块。修改内核配置时我们以当前版本运行的内核为蓝本,然后在新下载的WSL2-Linux-Kernel
源码配置中添加USB存储驱动模块。
首先复制当前内核的配置文件。
cp /proc/config.gz config.gz
gunzip config.gz
mv config .config
接下来使用命令‘make menuconfig’修改内核配置
make menuconfig
以下是我修改过的内容的导航,如何修改见截图。
menuconfig -> Device Drivers --> USB support ---> USB Mass Storage support
💁?♂ 使用上下键移动,按回车键进入下级目录,按空格键进行修改。其中[] <>中为空的,系统内核不加载该选项。[] <>中为*号时系统内核启动时会自动加载该选项。
完成上述操作后,使用方向箭头移动到上,按下回车保存配置。然后再移动到一层层的退出菜单。
至此我们已经在内核配置文件中添加好了对USB存储设备的支持,接下来使用下面的命令重新编译内核。
在编译之前还需要配置文件中的CONFIG_X86_X32
关闭,否则接下来的编译中会报错。
vim .config
保存.config,执行下述命令编译内核。
sudo make -j$(nproc)
sudo make modules_install -j$(nproc)
sudo make install -j$(nproc)
执行完上述命令后,会在WSL-Linux-Kernel
目录下产生一个vmlinux的文件,这个vmlinux就是我们编译的新内核。
通过前面的步骤,我们已经编译生成了带有USB驱动存储模块的新内核,那么接下来就让WSL Ubuntu 启用新的内核。
首先将新内核复制到C盘根目录C:\Sources
目录下(当然也可以是其他目录,如果您的C盘无此目录,需要先新建)。
cp -rf vmlinux /mnt/c/Sources
在你的用户根目录下,新建一个.wslconfig
文件,输入以下内容。
[wsl2]
kernel=c:\\Sources\\vmlinux
💁?♂ 如果你的内核文件不是在c:\Sources
目录下,记得要改成你vmlinux文件所在目录。
💁?♂ 当前用户目录可以通过在开始菜单中运行%UserProfile%来打开。
完成以上操作后,退出WSL Ubuntu,在powershell中使用命令wsl --shutdown
关闭WSL。然后重启你的windows。
系统重启后,首先登录WSL Ubuntu,然后重复前面的步骤,将USB设备连接到WSL Ubuntu系统。此时在WSL中通过lsblk
命令就能看到U盘了。
从上图可以看出,我的U盘分区是/dev/sdd4,为了挂载这个U盘,首先需要为U盘指定一个挂载点,这里我在‘/mnt’目录下新建了一个usbstore
目录。
sudo mkdir /mnt/usbstore
接下来把‘/dev/sdd4’挂载到新建的usbstore目录。
mount /dev/sdd4 /mnt/usbstore/
进入/mnt/usbstore
目录就能查看我们U盘中的内容了。
当然,在U盘中新建文件夹也是没问题,说明新的内核已经完成支持USB设备的读写挂载了。
好了,今天的教程就到这里了,如果大家有什么问题,或者本文中有什么错误欢迎大家留言。