0. 前言
在linux内核开发,针对一些被编译成module的模块调试,很多时候也需要整编内核(包括built-in和module的),生成deb包之后给到测试方,通过dpkg进行安装。但是deb的编译耗时较长,我自己调试驱动模块的时候一般是直接make内核,只生成目标模块不去编译deb包,然后将目标模块替换掉调试设备上现有的模块,首次编译基本也要半小时以上。
能不能像之前自己写的模块一样(自己写一个内核模块),单独在核外进行编译呢?
也是可以的!参考如下方式。
1. 将linux内核模块在核外进行编译
1.0 前置知识
内核模块编译要依赖于内核头文件,把模块放在内核源码树中一起编译时不用担心引用问题。但是单独拿出来编译,模块源码在内核源码中的tag点、编译机的内核版本、目标主机的内核版本可能都不一样,因此一定要清楚自己到底是需要做什么?
以内核的phylink.ko作为示例,演示一下怎么把它在核外(内核源码树以外)进行编译。
1.1 核外编译phylink.ko
先看phylink.ko随内核源码一起编译时是怎么生成的:
- Makefile中指明了phylink的目标文件:
//drivers/net/phy/Makefile
obj-$(CONFIG_PHYLINK) += phylink.o
可以看到编译这个模块只需要一个phylink.c文件,并且要依赖于编译配置CONFIG_PHYLINK。这个CONFIG_PHYLINK编译配置在Kconfig中声明:
config PHYLINK
tristate
depends on NETDEVICES
select PHYLIB
select SWPHY
help
PHYlink models the link between the PHY and MAC, allowing fixed
configuration links, PHYs, and Serdes links with MAC level
autonegotiation modes.
- 重新写Makefile
其实很简单,就当做自己新写的模块一样写Makefile就行了:
# 只需要phylink.c
filename = phylink
# -m编译成ko模块
obj-m = $(filename).o
KSRC = /lib/modules/`uname -r`/build
all:
make -C $(KSRC) M=$(PWD) modules
clean:
make -C $(KSRC) M=$(PWD) clean
- 把phylink的源码从内核中拿出来
可以通过软链接的方式(本机调试)或者直接拷贝到目标主机上编译。
我在本机上做演示,直接使用软链接了:
- 编译
直接make,发现有报错:
看了一下phylink.c的代码,是因为其中引用了两个同级目录下的头文件:
把这俩头文件全复制(或者软链接)到编译目录下来:
再编译:
产物:
- 替换调试
将刚编译好的phylink.ko替换/lib/modules/xxxx/kernel/drivers/net/phy/phylink.ko,重启设备或者重启模块进行调试。