WSL2内核编译_添加SocketCAN支持
文章目录wsl更新内核默认不支持SocketCANwsl内核源码下载Windows 和 Linux 区分大小写之间的差异Ubuntu18.04内核5.10.60.1特有问题修改内核添加can支持编译配置SocketCAN VXCAN测试参考wsl更新内核microsoft/WSL2-Linux-Kernel github先列一下常用操作# 管理员身份运行powershell# 列出wsl的分支和版
文章目录
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坑人的地方
同样创建了aa
和aA
两个文件, 虚拟机就可以, 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
, 也能正常收到消息. 这说明两者运行的应该是一个内核, 但又保留了各自的环境, 比虚拟机开两个系统省了很多资源, 又能最大限度的发挥硬件的性能.
参考
如下
- SocketCAN/can-utils on Windows, reddit
- Add SocketCAN support #5533, microsoft/WSL, github
- wsl2 添加socketCAN 支持, 知乎lyf
- build socketcan and tools in WSL2, csdn spacecraft
欢迎扫描二维码关注本人微信公众号, 及时获取最新文章:
更多推荐
所有评论(0)