关于WSL2你应该知道的
关于WSL2你应该知道的
一个默认的前提是你已经打算去使用WSL2,因此关于虚拟机(一般意义上)和WSL2优劣的讨论会被避免。
这篇文章主要记录笔者使用WSL2进行开发过程中遇到的问题以及相应的解决方法。
linux-headers
在linux下进行驱动开发需要相应的内核头文件,在使用虚拟机的情况下可以通过linux-headers-$(uname -r)
进行下载,但是在WSL2下该功能并不被支持,因为WSL2使用的linux内核时microsoft特别定制过的,以笔者的电脑为例,如果你运行uname -r
,得到的输出如下:
5.15.153.1-microsoft-standard-WSL2
按照文档安装的WSL2并不会自带源码,因此需要去GitHub下载相应的源代码 WSL2-Linux-Kernel。
源码下载完成后需要安装相应的依赖:
sudo apt install libelf-dev build-essential pkg-config
sudo apt install bison build-essential flex libssl-dev libelf-dev bc
之后开始编译源代码:
tar -zvxf WSL2-Linux-Kernel-linux-msft-wsl-5.15.153.1.tar.gz
cd WSL2-Linux-Kernel-linux-msft-wsl-5.15.153.1
zcat /proc/config.gz > .config
make -j $(nproc)
sudo make -j $(nproc) modules_install
编译过程中可能遇到一些错误,一些可能的参考如下:
sudo apt install bison flex # flex&bison相关报错
sudo apt-get install libssl-dev # <openssl/bio.h>相关报错
sudo apt-get install dwarves # BTF相关报错
最后为了方便编程做一个软链接:
sudo ln -s /path/to/WSL2-Linux-Kernel-linux-msft-wsl-5.15.153.1 /usr/src/linux-headers-5.15.153.1-microsoft-standard-WSL2
如果你做完了上述的内容,在模块开发上面就应该比较顺利了,但是当你在试图加载模块的时候,大概率还是会遇到问题。笔者在开发过程中分别遇到过Invalid module format
和Invalid parameter
两种报错,而且两次报错中我的代码时相同的,唯一不同的时Ubuntu的版本,我在Ubuntu20.04上遇到的时Invalid module format
,而在Ubuntu22.04和Ubuntu24.04上遇到的则是后者。关于前者的具体报错和日志信息可以参考笔者在Stackoverflow的提问 Meeting Invalid module format
when insmod mymodule.ko。后者的日志输出如下:
[14962.221382] BPF:[133427] Invalid name_offset:2397115
[14962.222417] failed to validate module [mychardev] BTF: -22
单看日志的话似乎时BPF版本的问题,但是实际上这个问题来自于WSL2内核本身。发行的WSL2内核本身就禁止了模块的加载,一个解决方法是编译并使用自己的WSL2内核。
在之前的编译步骤结束之后,在/path/to/WSL2-Linux-Kernel-linux-msft-wsl-5.15.153.1/arch/x86/boot/bzimage
可以找到bzimage文件,把它拷贝到Windows下的%userprofile%
下。关于环境变量%userprofile%
,你可以通过下面的方式查看:
# cmd
echo %userprofile%
# powershell
echo $env:userprofile
拷贝结束后创建并编辑%userprofile%\.wslconfig
文件,内容如下:
[wsl2]
kernel=C:\\Users\\WIN10_USER\\bzimage
多的一个\
作为转义字符是必须存在的,而WIN10_USER
作为占位符在使用时换成自己的Windows用户名。此外结尾不要加上空格以避免潜在的bug。
最后,运行wsl --shutdown
并重启WSL2,此时你应该可以成功加载模块了。
以上方法来自 Hannah J。