linux内核经常涉及编译某一项驱动代码的场景,本次以网卡驱动e1000为例说明整个步骤流程。
首先编译内核驱动不必要编译整个内核,但编译的驱动代码必须要和要安装的内核版本保持一致,否则经常会出现无法加载模块。
在编译驱动前,最好要保证3个版本一致:
1.`uname -r`当前系统内核版本 ----为了能够安装到本系统
2.yum install kernel-devel 版本 ----kernel-devel保证编译驱动时kernel的源码
3.某驱动src版本 ----保证编译时不会出现编译错误
1.当前系统版本
这个没什么好说的,直接按照当前系统的kernel版本统一即可,毕竟编译后的驱动时安装到本系统的,本次统一为4.18.0-348版本。
2.kernel-devel
注意kernel-devel版本一定要和当前系统本身kernel版本一致,这样编译后的驱动模块才能顺利安装。
在安装完kernel-devel后,系统会在/lib/modules/下自动创建kernel的目录,该目录下有个build软连接,指向/usr/src/`uname -r`/下的kernel源码目录,这个目录也是我们后期单独编译驱动时,make命令中-C选项指定的内核源码目录。
3.驱动源码e1000
本次intel 网卡驱动e1000的代码是从kernel-4.18.0-348.el8.src.rpm解压后的kernel-4.18.0中单独拷贝出来。
rpm -i kernel-4.18.0-348.el8.src.rpm后会在当前用户家目录下生成rpmbuild目录,将其中的linux-.tar.xz解压后,在kernel源码/drivers/net/ethernet/intel/e1000/拷贝出e1000驱动的源码文件到/root下。
4.编译驱动
原始的e1000源码由于是在kernel中整体构建,所以其自带的Makefile中没有可构建的目标,所以我们需要改动下Makefile,让其有具体的target为编译e1000.o
修改后的makefile如下,所有驱动源码单独编译时的Makefile均可用此模板,只需要修改modname以及相应的.o组成文件:
# cat e1000/Makefile
MODNAME = e1000
PWD = $(shell pwd)
KDIR ?= /lib/modules/$(shell uname -r)/build
obj-m += $(MODNAME).o
$(MODNAME)-y = \
e1000_main.o \
e1000_hw.o \
e1000_ethtool.o \
e1000_param.o
all:
make -C $(KDIR) M=$(PWD) src=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) src=$(PWD) clean
修改好Makefile后,就可以直接make编译了
编译后insmod或modprobe完成加载