wsl更新内核

microsoft/WSL2-Linux-Kernel github

先列一下常用操作

# 管理员身份运行powershell

# 列出wsl的分支和版本号
# Ubuntu-18.04 是 wsl1
# Ubuntu 是 wsl2, 是Ubuntu20
> wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-18.04    Stopped         1
  Ubuntu          Stopped         2
  
# 关闭运行的子系统
# 后面可以加NAME, 如只关闭Ubuntu20的 wsl --shutdown Ubuntu
> wsl --shutdown

# Ubuntu-18.04 切换成wsl2
> wsl --set-version Ubuntu-18.04 2
正在进行转换,这可能需要几分钟时间...
有关与 WSL 2 的主要区别的信息,请访问 https://aka.ms/wsl2
# 有时候得打回车才能看到 转换完成 四个大字

新的linux内核往往支持更丰富的功能, 但之前从win10应用商店下载的wsl2的ubuntu只是4.19的内核, 而最新的稳定版已经更新到了5.10.y, wsl更新内核也很简单

# 管理员身份运行powershell

# 关闭子系统
> wsl --shutdown
# 不指定, 更新所有linux内核
> wsl --update

# Ubuntu-18.04 和 Ubuntu 都更新到了 5.10.60.1
$ uname -a
Linux DESKTOP-N0N0EQI 5.10.60.1-microsoft-standard-WSL2 #1 SMP Wed Aug 25 23:20:18 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

# 不想升了可以用rollback命令回滚
# 其实内核文件为 C:\Windows\System32\lxss\tools\kernel
# 内核备份文件为 C:\Windows\System32\lxss\tools\kernel.rollback

本篇是在wsl2中测试通过的, 未在wsl1测试.

默认不支持SocketCAN

如下

# can-raw, vcan, vxcan都没有
$ sudo modprobe can-raw
modprobe: FATAL: Module can-raw not found in directory /lib/modules/5.10.60.1-microsoft-standard-WSL2

可以通过下载内核源码, make menuconfig加入can的支持, 下面记录下踩坑的地方

wsl内核源码下载

如下

$ uname -a
Linux DESKTOP-N0N0EQI 5.10.60.1-microsoft-standard-WSL2 #1 SMP Wed Aug 25 23:20:18 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

# https://github.com/microsoft/WSL2-Linux-Kernel/releases
# 下载对应的 linux-msft-wsl-5.10.60.1

如图

在这里插入图片描述

大小220MB

Windows 和 Linux 区分大小写之间的差异

先来看一下wsl坑人的地方

在这里插入图片描述

同样创建了aaaA两个文件, 虚拟机就可以, wsl直接认为是一个文件, 好巧不巧的是, linux内核有几个同一目录下的文件, 只是大小写不同, 如 include/uapi/linux/netfilter目录下的:

在这里插入图片描述

这在wsl里面解压会出现严重的问题:

  • unzip, 解压巨慢, 等半天提示 replace WSL2-Linux-Kernel-linux-msft-wsl-5.10.60.1/include/uapi/linux/netfilter/xt_connmark.h? [y]es, [n]o, [A]ll, [N]one, [r]ename:, 输r的话, 又不知道到底有多少, 输N的话又不知道哪个是重复的, 还得一遍一遍编译查错
  • tar, 默认直接覆盖了

这里用管理员身份运行windows下的Bandizip, 把内核压缩包拖进去, 解压, 提示存在相同文件时. 点重命名, 应用到全部文件

在这里插入图片描述

解压完, 用everything搜索文件夹, 输入(, 可以看到存在下面区分大小写的文件:

在这里插入图片描述

这个时候还不能重命名, 微软官方给出了说明和解决办法:

调整区分大小写

标准行为:

  • Windows 文件系统将文件和目录名称视为不区分大小写。 FOO.txt 和 foo.txt 将被视为等效文件。

  • Linux 文件系统将文件和目录名称视为区分大小写。 FOO.txt 和 foo.txt 将被视为不同文件。

自 Windows 10 内部版本 17107 开始,支持按目录区分大小写。使用名为 system.wsl_case_sensitive 的扩展属性公开区分大小写, 默认还是不区分, 需要管理员权限更改目录该属性(似乎不支持嵌套, 所以目录一个一个改)

# 管理员身份运行powershell
# 管理员身份运行powershell
# 管理员身份运行powershell

> cd D:\wsl\u18\WSL2-Linux-Kernel-linux-msft-wsl-5.10.60.1
# 确保文件夹不被子系统打开, 可以 wsl --shutdown
# 设置文件夹区分大小写
> fsutil.exe file setCaseSensitiveInfo .\include\uapi\linux\netfilter
> fsutil.exe file setCaseSensitiveInfo .\include\uapi\linux\netfilter_ipv4
> fsutil.exe file setCaseSensitiveInfo .\include\uapi\linux\netfilter_ipv6
> fsutil.exe file setCaseSensitiveInfo .\net\netfilter
> fsutil.exe file setCaseSensitiveInfo .\tools\memory-model\litmus-tests

之后就可以在everything软件中直接重命名文件(去掉(2), 包括(2)之前的空格)

Ubuntu18.04内核5.10.60.1特有问题修改

参考 make of 5.10.60.1 fails #7558, Ubuntu 18.04(gcc 7.5.0)为了规避 scripts/Makefile.build:280: recipe for target 'drivers/hv/dxgkrnl/dxgmodule.o' failed 错误, 修改/drivers/hv/dxgkrnl/dxgmodule.c文件, 默认的是

在这里插入图片描述

需要把const int改为#define, 并加上结尾的换行符\, 去掉=;

/* vGPU VM bus channel instance ID */
#define DXGK_VMBUS_CHANNEL_ID_OFFSET	192
/* DXGK_VMBUS_INTERFACE_VERSION (u32) */
#define DXGK_VMBUS_VERSION_OFFSET	 DXGK_VMBUS_CHANNEL_ID_OFFSET + \
					  sizeof(guid_t)
/* Luid of the virtual GPU on the host (struct winluid) */
#define DXGK_VMBUS_VGPU_LUID_OFFSET	 DXGK_VMBUS_VERSION_OFFSET + \
					  sizeof(u32)
/* The guest writes its capavilities to this adderss */
#define DXGK_VMBUS_GUESTCAPS_OFFSET	 DXGK_VMBUS_VERSION_OFFSET + \
					  sizeof(u32)

Ubuntu20(gcc 9.3.0)或者最新的5.10.74.3没有这个问题.

内核添加can支持

如下

# 安装编译依赖
$ sudo apt install build-essential flex bison libssl-dev libelf-dev

$ cd /mnt/d/wsl/u18/WSL2-Linux-Kernel-linux-msft-wsl-5.10.60.1/

$ zcat /proc/config.gz > .config
$ make menuconfig

接下来就是CAN的配置

Networking support->按空格把CAN bus subsystem support选为M

在这里插入图片描述

通通选上

在这里插入图片描述

通通选上, CAN USB interfaces里面是支持的USB CAN设备, 有设备的就进去选上, 我用不到USB的CAN设备, 就不进了

在这里插入图片描述

在这里插入图片描述

然后一路<Exit>退出来即可

编译配置

先来编译module

# 默认的 /lib/modules 是空的

# 压上全部cpu, i7-8086K 第一次仍然需要30min左右
$ make modules -j $(nproc)
$ sudo make modules_install

# .ko文件就安装到了/lib/modules下面
$ tree /lib/modules
/lib/modules
└── 5.10.60.1-microsoft-standard-WSL2
    ├── build -> /mnt/d/wsl/u18/WSL2-Linux-Kernel-linux-msft-wsl-5.10.60.1
    ├── kernel
    │   ├── drivers
    │   │   └── net
    │   │       └── can
    │   │           ├── c_can
    │   │           │   └── c_can.ko
    │   │           ├── cc770
    │   │           │   └── cc770.ko
    │   │           ├── dev
    │   │           │   └── can-dev.ko
    │   │           ├── ifi_canfd
    │   │           │   └── ifi_canfd.ko
    │   │           ├── kvaser_pciefd.ko
    │   │           ├── m_can
    │   │           │   ├── m_can.ko
    │   │           │   └── m_can_platform.ko
    │   │           ├── peak_canfd
    │   │           │   └── peak_pciefd.ko
    │   │           ├── sja1000
    │   │           │   └── sja1000.ko
    │   │           ├── slcan.ko
    │   │           ├── softing
    │   │           │   └── softing.ko
    │   │           ├── vcan.ko
    │   │           └── vxcan.ko
    │   └── net
    │       └── can
    │           ├── can-bcm.ko
    │           ├── can-gw.ko
    │           ├── can-isotp.ko
    │           ├── can-raw.ko
    │           ├── can.ko
    │           └── j1939
    │               └── can-j1939.ko
    ├── modules.alias
    ├── modules.alias.bin
    ├── modules.builtin
    ├── modules.builtin.bin
    ├── modules.builtin.modinfo
    ├── modules.dep
    ├── modules.dep.bin
    ├── modules.devname
    ├── modules.order
    ├── modules.softdep
    ├── modules.symbols
    ├── modules.symbols.bin
    └── source -> /mnt/d/wsl/u18/WSL2-Linux-Kernel-linux-msft-wsl-5.10.60.1

18 directories, 31 files

接着编译内核

# 为了得到内核文件 vmlinux, 约68.6MB
$ make -j $(nproc)

# 下面这句不运行也暂未发现问题
# $ sudo make install

使用新编译出的内核

# 拷贝新编译出来的最原始的未压缩内核文件 vmlinux 到 windows 用户目录, karoto是我的windows用户名
# 如果是第一次可以直接在ubuntu内拷贝, 第二次需要关闭wsl, 在powershell拷贝
> wsl --shutdown
> cp D:\wsl\u18\WSL2-Linux-Kernel-linux-msft-wsl-5.10.60.1\vmlinux C:\Users\karoto\
> code .wslconfig
# 这里用vscode, 也可以用其他编辑器

[wsl2]
kernel=C:\\Users\\karoto\\vmlinux

# karoto是我的windows用户名

重新启动Ubuntu18.04, 发现已经用的是新编译出来的内核(Ubuntu20也是同一个内核), 版本号和编译时间都对得上

$ uname -a
Linux DESKTOP-N0N0EQI 5.10.60.1-microsoft-standard-WSL2 #2 SMP Wed Dec 1 20:04:14 CST 2021 x86_64 x86_64 x86_64 GNU/Linux

SocketCAN VXCAN测试

如下

# 用于支持 candump cansend canbusload等
$ sudo apt install can-utils

# 没有这个会报错 
# socket: Protocol not support
# 或 socket: Address family not supported by protocol
$ sudo modprobe can-raw

$ sudo modprobe vxcan
$ sudo ip link add dev vcan0 type vxcan
$ sudo ip link set dev vcan0 up
$ sudo ip link set dev vxcan0 up
# 用ip link 和 ifconfig 检验一下

# 接收
$ candump -ta -x vcan0

# 发送 标准帧 扩展帧 CANFD标准帧 CANFD扩展帧测试
$ cansend vxcan0 123#11.22.33.44.55.66.77.88
$ cansend vxcan0 12345678#11.22.33.44.55.66.77.88
$ cansend vxcan0 124##3.11.22.33.44.55.66.77.88.99
$ cansend vxcan0 12345679##3.11.22.33.44.55.66.77.88.99

# 接收结果
# 这里TX不太好解释... 但确实是收到的
$ candump -ta -x vcan0
 (1638360868.731386)  vcan0  TX - -  123   [8]  11 22 33 44 55 66 77 88
 (1638360878.449080)  vcan0  TX - -  12345678   [8]  11 22 33 44 55 66 77 88
 (1638360882.465867)  vcan0  TX B E       124  [12]  11 22 33 44 55 66 77 88 99 00 00 00
 (1638360897.055933)  vcan0  TX B E  12345679  [12]  11 22 33 44 55 66 77 88 99 00 00 00

# dmesg下面的信息
$ dmesg
[  134.963328] can: controller area network core
[  134.963349] NET: Registered protocol family 29
[  134.964407] can: raw protocol
[  139.418813] vxcan: Virtual CAN Tunnel driver

比较有意思的是, 同时开Ubuntu18.04和Ubuntu20, 在Ubuntu20发送cansend vxcan0 xxx, 在Ubuntu18中 candump -ta -x vcan0, 也能正常收到消息. 这说明两者运行的应该是一个内核, 但又保留了各自的环境, 比虚拟机开两个系统省了很多资源, 又能最大限度的发挥硬件的性能.

参考

如下

欢迎扫描二维码关注本人微信公众号, 及时获取最新文章:
在这里插入图片描述

Logo

更多推荐