linux--编译驱动模块【虚拟网卡 tun】

发布于:2025-02-11 ⋅ 阅读:(44) ⋅ 点赞:(0)

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命令

tar -zxvf linux-5.10.160.tar.gz

2.2 安装控制台应用程序依赖库,其他库

sudo apt install build-essential libncurses5-dev
sudo apt install flex bison libssl-dev

2.3 普通用户模式操作

root 用户操作用改变文件权限,建议普通用户模式操作。

2.4 然后配置需要编译的模块

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 文件

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 编译模块

make modules
make modules -j 3
  • 虚拟机中:
    开了 3 个线程,编译后多占用 19G,花了 90 分钟。【46G -> 27G】
  • Arm 板子上:
    开了 7 个线程,编译后多占用 3G,花了 10 分钟。
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$

在这里插入图片描述

报错处理一:缺少证书

  • 编译内核报错:
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文件,注释掉下面两行
CONFIG_SYSTEM_TRUSTED_KEYS
CONFIG_SYSTEM_REVOCATION_KEYS

或者使用下面命令处理

scripts/config --disable SYSTEM_TRUSTED_KEYS
scripts/config --disable SYSTEM_REVOCATION_KEYS

执行完后 make clean 后重新编译

报错处理二:version magic 不对,关闭 preempt

// 查看 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

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 复制加载模块

编译完成后,可以想内核中加载模块了:

cp linux-source-5.10.160/drivers/net/tun.ko /lib/modules/5.10.160

将编译过后的 tun.ko 复制到 /lib/modules/xxx/ 目录下去,xxx 是一个和你当前内核版本号相关的目录,一般而言,这个目录下也就xxx这么一个目录。
接下来是分析可载入模块的相互依赖性:

depmod

验证和加载

如果得到类似下面的输出,基本上你的安装就成功了

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

参考

1、buntu 16.04虚拟网络设备tun安装
2、谁知道如何安装tun模块
3、2. 编译 Linux 固件 (内核版本 5.10)
4、Rockchip RK3588 - Rockchip Linux SDK编译
5、3. linux-headers 和 linux-image
6、Linux下编写和加载 .ko 文件(驱动模块文件)


网站公告

今日签到

点亮在社区的每一天
去签到