linux--编译驱动模块【虚拟网卡 tun】
- [1 介绍](#1 介绍)
- [2 操作](#2 操作)
-
- [2.1 源码 linux-5.10.160](#2.1 源码 linux-5.10.160)
- [2.2 安装控制台应用程序依赖库,其他库](#2.2 安装控制台应用程序依赖库,其他库)
- [2.3 普通用户模式操作](#2.3 普通用户模式操作)
- [2.4 然后配置需要编译的模块](#2.4 然后配置需要编译的模块)
- [2.5 关闭 preempt](#2.5 关闭 preempt)
- [2.6 开启 bpf【未成功,放弃】](#2.6 开启 bpf【未成功,放弃】)
- [2.7 编译模块](#2.7 编译模块)
-
- 报错处理一:缺少证书
- [报错处理二:version magic 不对,关闭 preempt](#报错处理二:version magic 不对,关闭 preempt)
- 报错处理三:bpf_dispatcher_xdp_func
- [2.8 复制加载模块](#2.8 复制加载模块)
- 参考
1 介绍
.ko 文件是 kernel object 文件(内核模块),该文件的意义就是把内核的一些功能移动到内核外边, 需要的时候插入内核,不需要时卸载。这样可以缩小内核体积,又使用方便。
2 操作
2.1 源码 linux-5.10.160
https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/
进入网页,往下拉,上面都是补丁内容,下面是内核源码,找一个5.10版本开头的,tar.gz结尾的,下载下来就好,速度很快的。
然后进行解压缩,进入压缩包的目录,输入下面的shell命令
shell
tar -zxvf linux-5.10.160.tar.gz
2.2 安装控制台应用程序依赖库,其他库
shell
sudo apt install build-essential libncurses5-dev
sudo apt install flex bison libssl-dev
2.3 普通用户模式操作
root 用户操作用改变文件权限,建议普通用户模式操作。
2.4 然后配置需要编译的模块
shell
make menuconfig
找到 Device Drivers -->,回车选择:
继续找到 Network Device Support -->,回车选择:
找到 Universal TUN/TAP device driver support,看到前面是<*>,键盘输入 M,变成<M>,退出并保存,回到终端:
注:[*],<*>表示编译进内核,<M>表示编译成模块,如果不知道某选项为何时,且有模块可选时,那么就可以直接选择为模块,如果有疑惑,可以去翻鸟哥的 linux私房菜基础篇这本书.
生成 .config 文件,在源码目录中。
2.5 关闭 preempt
2.6 开启 bpf【未成功,放弃】
修改 .config 文件
shell
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_NET_CORE=y
CONFIG_NET_RX_BUSY_POLL=y
CONFIG_BPF_JIT=y
CONFIG_HAVE_EBPF_JIT=y
CONFIG_BPF_EVENTS=y
CONFIG_XDP_SOCKETS=y
2.7 编译模块
shell
make modules
make modules -j 3
- 虚拟机中:
开了 3 个线程,编译后多占用 19G,花了 90 分钟。【46G -> 27G】 - Arm 板子上:
开了 7 个线程,编译后多占用 3G,花了 10 分钟。
shell
bot@u18:~/Desktop/linux-5.10.160/drivers/net$ file tun.ko
tun.ko: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV),
BuildID[sha1]=be925458aa575c50f44b963f59e3e2dff6dbd3bc, with debug_info, not stripped
bot@u18:~/Desktop/linux-5.10.160/drivers/net$
报错处理一:缺少证书
- 编译内核报错:
shell
Generating X.509 key generation config
CC certs/common.o
make[1]: *** No rule to make target 'debian/canonical-revoked-certs.pem',
needed by 'certs/x509_revocation_list'. Stop.
make[1]: *** Waiting for unfinished jobs....
CC certs/blacklist.o
CC arch/x86/events/intel/knc.o
Makefile:1837: recipe for target 'certs' failed
make: *** [certs] Error 2
make: *** Waiting for unfinished jobs....
- 分析:缺少证书
- 处理:解决办法
在下载的内核文件中搜索.config文件,注释掉下面两行
shell
CONFIG_SYSTEM_TRUSTED_KEYS
CONFIG_SYSTEM_REVOCATION_KEYS
或者使用下面命令处理
shell
scripts/config --disable SYSTEM_TRUSTED_KEYS
scripts/config --disable SYSTEM_REVOCATION_KEYS
执行完后 make clean 后重新编译
报错处理二:version magic 不对,关闭 preempt
shell
// 查看 tun 驱动模块信息
rockchip@ubuntu:/lib/modules/5.10.160$ sudo modinfo tun
filename: /lib/modules/5.10.160/tun.ko
alias: devname:net/tun
alias: char-major-10-200
license: GPL
author: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
description: Universal TUN/TAP device driver
depends:
intree: Y
name: tun
vermagic: 5.10.160 SMP preempt mod_unload aarch64
// 加载模块
rockchip@ubuntu:/lib/modules/5.10.160$ sudo modprobe tun
modprobe: ERROR: could not insert 'tun': Exec format error
// 查看模块信息
rockchip@ubuntu:/lib/modules/5.10.160$ file tun.ko
tun.ko: ELF 64-bit LSB relocatable, ARM aarch64, version 1 (SYSV), BuildID[sha1]=b1b0488c550705da933a51f4d2111c175edddf52, with debug_info, not stripped
// 查看系统内核版本
rockchip@ubuntu:/lib/modules/5.10.160$ uname -r
5.10.160
// 查看相关错误日志
rockchip@ubuntu:/lib/modules/5.10.160$ dmesg | grep tun
[ 3.103039] dwmmc_rockchip fe2d0000.mmc: Successfully tuned phase to 135
[ 2322.458575] tun: version magic '5.10.160 SMP preempt mod_unload aarch64' should be '5.10.160 SMP mod_unload aarch64'
[ 2601.434178] tun: version magic '5.10.160 SMP preempt mod_unload aarch64' should be '5.10.160 SMP mod_unload aarch64'
rockchip@ubuntu:/lib/modules/5.10.160$
报错处理三:bpf_dispatcher_xdp_func
shell
rockchip@ubuntu:/lib/modules/5.10.160$ sudo modprobe tun
modprobe: ERROR: could not insert 'tun': Unknown symbol in module, or unknown parameter (see dmesg)
rockchip@ubuntu:/lib/modules/5.10.160$ dmesg | grep tun
[ 8195.853824] tun: Unknown symbol bpf_dispatcher_xdp_func (err -2)
bpf_dispatcher_xdp_func 是 5.6 版本中引入的。
需要确保在内核配置中启用了 BPF 支持。可以通过运行 make menuconfig 命令来访问内核配置菜单,并确保以下选项被启用:
- CONFIG_BPF=y
- CONFIG_BPF_SYSCALL=y
- CONFIG_NET_CORE=y
- CONFIG_NET_RX_BUSY_POLL=y
- CONFIG_BPF_JIT=y
- CONFIG_HAVE_EBPF_JIT=y
- CONFIG_BPF_EVENTS=y
- CONFIG_XDP_SOCKETS=y
2.8 复制加载模块
编译完成后,可以想内核中加载模块了:
shell
cp linux-source-5.10.160/drivers/net/tun.ko /lib/modules/5.10.160
将编译过后的 tun.ko 复制到 /lib/modules/xxx/ 目录下去,xxx 是一个和你当前内核版本号相关的目录,一般而言,这个目录下也就xxx这么一个目录。
接下来是分析可载入模块的相互依赖性:
shell
depmod
验证和加载
如果得到类似下面的输出,基本上你的安装就成功了
shell
rockchip@ubuntu:/lib/modules/5.10.160$ sudo modinfo tun
filename: /lib/modules/5.10.160/tun.ko
alias: devname:net/tun
alias: char-major-10-200
license: GPL
author: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
description: Universal TUN/TAP device driver
depends:
intree: Y
name: tun
vermagic: 5.10.160 SMP preempt mod_unload aarch64
rockchip@ubuntu:/lib/modules/5.10.160$ modprobe tun
rockchip@ubuntu:/lib/modules/5.10.160$ lsmod | grep tun
tun 28672 0
参考
4、Rockchip RK3588 - Rockchip Linux SDK编译