The Problems of Using OpenEuler WSL

The Problems of Using OpenEuler WSL

记录一下在OS课上使用OpenEuler WSL遇到的坑

OpenEuler 官方下载WSL系统的脚本十分炸裂,能在x86架构的机器上安装MIPS架构的结果,建议避雷,使用微软商店的软件包下载

本次实验的要求:

1.向OpenEuler系统,或者OpenKylin系统中,增加一个系统
调用/或内核模块,鼓励程序逻辑的多样化
2.撰写一个应用测试程序调用该系统调用/测试该内核模块
3.使用trace/ptrace/strace,或类似的系统跟踪工具来对该测试
程序进行跟踪调试

内核问题

问题描述

实验环境是在WSL2下使用OpenEuler,CentOS套壳

借鉴了一些网络上的代码后,对源码进行编译,下面是Makefile文件内容

1
2
3
4
5
6
7
8
9
obj-m:=syscall.o
PWD:= $(shell pwd)
KERNELDIR:= /lib/modules/$(shell uname -r)/build
EXTRA_CFLAGS= -O0

all:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
make -C $(KERNELDIR) M=$(PWD) clean

make后报错:

/lib/modules/5.15.146.1-microsoft-standard-WSL2/build: No such file or directory.

搜索后可知,WSL2的内核是修改过的,无法使用CentOS上游的内核头文件和modules文件,因此,我们需要手动编译并安装一个版本。

解决步骤

下载对应版本内核代码

首先查看系统内核版本

1
uname -r

5.15.146.1-microsoft-standard-WSL2

WSL git仓库,找到对应的release

1
git clone https://github.com/microsoft/WSL2-Linux-Kernel

编译和安装

1
2
3
cd WSL2-Linux-Kernel
LOCALVERSION= make KCONFIG_CONFIG=Microsoft/config-wsl -j8
sudo LOCALVERSION= make KCONFIG_CONFIG=Microsoft/config-wsl modules_install -j8

这个阶段会遇到较多报错,由于我使用的是CentOS和网络上大多资料使用的Ubuntu不同,因此需要安装的依赖也不一样,这里就直接放出一部分报错和安装的全部命令

fatal error: openssl/bio.h: No such file or directory
fatal error: libelf.h: No such file or directory
BTF: .tmp_vmlinux.btf: pahole (pahole) is not available Failed to generate BTF for vmlinux
Try to disable CONFIG_DEBUG_INFO_BTF
Warning: ‘make modules_install’ requires depmod. Please install it.

1
sudo dnf install bison flex openssl-devel elfutils-libelf-devel dwarves kmod

安装完这些以后,再重新运行上面的指令,这个时候就能发现没有问题了。

insmod问题

问题描述

当编译成功后,需要加载内核模块

1
sudo insmod randomizer.ko

这个时候终端抛出问题:

ERROR: could not insert module mymodule.ko: Invalid parameters

但是一番搜索后发现根本没有解决我的问题的方法,这时候查看日志

1
dmesg | tail

可以发现出现了这样的错误:

BPF:[xxxxx] Invalid name_offset:xxxxxx failed to validate module [mymodule] BTF: -22

在一篇博客中有这样的记录:

“rocky linux 9上面,内核编译设置默认打开了DEBUG_INFO_BTF_MODULES,这样所有模块里面都带有BTF信息。

运行时内核的BTF这个机制,如果模块缺少BTF信息(ELF的BTF段)那可以加载成功,但如果BTF的版本不匹配就拒绝加载。 使用源码自己编译内核时,虽然内核源码是一样的但生成的BTF还是不匹配的。 这样自己使用内核源码目录( 不是系统的/lib/modules/uname -r/build ) 编译一个模块出来, 在rocky linux的官方内核系统里面就没法使用了, modprobe 会返回“ bpf invalid name btf -22”错误。 但通常编译模块时,如果make bzImage 之后make clean 删掉vmlinux 后 编译模块时找不到vmlinux就不会BTF信息,通常还是可以正常使用的。 但有的模块使用了 register_btf_kfunc_id_set 函数 向系统注册BTF函数的,这种一定要求BTF 信息的就不行了。

反正这个BTF这个东西,自己编译第三方模块时最好就不要把BTF编译进去了,不然不同的内核小版本都没法兼容,即使同样的内核源码也是不行的。”

可以看到其实是BTF的问题,联系到上面出现的一个报错:

BTF: .tmp_vmlinux.btf: pahole (pahole) is not available Failed to generate BTF for vmlinux
Try to disable CONFIG_DEBUG_INFO_BTF
Warning: ‘make modules_install’ requires depmod. Please install it.

我们就要在这上面下文章,一开始,我们借助下载dwarves解决了这个报错

而在这里,我们就需要去disable CONFIG_DEBUG_INFO_BTF

因此引出一种可行办法,也就是:

make menuconfig

配置内核,生成.config文件

然后在.config文件中修改

CONFIG_DEBUG_INFO_BTF=n

但是由于一些奇怪的原因,我无法使用 make menuconfig,于是,我借助了另一种思路

删掉vmlinux 后 编译模块时找不到vmlinux就不会BTF信息

实际上是阴差阳错地,我在WSL2-Linux-Kernel目录下执行make clean,清除了所有*.o文件,然后make重新编译了一次,这时候神奇的事情发生了,尽管我仍然没有.config文件,但是当我使用命令

1
sudo insmod randomizer.ko

并没有任何报错出现,这时候再用

1
dmesg | tail

查看内核日志和分配给模块的主设备号时

BPF:[xxxxx] Invalid name_offset:xxxxxx failed to validate module [mymodule] BTF: -22

module has been loaded: xxx

BTF的问题没有消失,但是我们绕开了

接着创建设备文件

1
sudo mknod /dev/mymodule c xxx 0

运行测试程序就可以发现成功了。

参考资料:

WSL 运行make提示/lib/modules/xxx/build: No such file or directory. Stop.错误解决办法

Btf版本不匹配导致内核模块加载失败的问题

kernel 源码升级