RK3399编译riffa续

     上一篇记录了编译在NanoPC-T4上编译riffa的曲折过程,但当时虽然编译成功了,但却无法加载模块,提示“Invalid module format”,并在这上面卡了很长时间。当时通过度娘知道应该是内核版本匹配的问题,由于开发板原厂提供的系统镜像中并未包含头文件,而且在系统 中也没找到.config文件,期间有发邮件到友善群里提供的技术支持邮箱索要官方内核对应的头文件包,按群公告要求也对问题进行了详细的描述,但到现在也没收到回复的邮件,更不要说技术支持了~~没法,谁叫咱是菜鸟呢,也许咱的问题别人根本就不当一回事,还是自己折腾吧。

    还是从最简单最基本的Hello驱动例程开始,在网上搜了相关教程,在T4编译成功但无法加载,依旧提示“Invalid module format”,然后在虚拟机上编译,加载成功,然后又在树莓派2上编译,发现树莓派的系统竟然也没有自带头文件,有apt-cache search有rpi2的头文件安装包,虽然版本不对,但死马当活马,直接apt-get install了,然后软链接过去,编译成功,但加载竟然也提示“Invalid module format”,这让我增加了内核不匹配的判断的信心,基于对树莓派资料丰富的信心,我相信虽然系统没有自带内核头文件,但肯定有关于安装头文件的说明,于是在树莓派官方github的文档中找到了安装头文件的说明,原来是sudo apt-get install raspberrypi-kernel-headers就自动安装对应版本的头文件了,期间由于hello的Makefile文件不兼容高版本内核(应该是),导致make时还自动编译内核自带的modules,由于没有源码,自然是无法成功了,于是又折腾了源码(说起来都是泪啊~),最后能正确编译的Makefile如下:
obj-m:=hello.o
KDIR:=/lib/modules/$(shell uname -r)/build

PWD:=$(shell pwd)

modules:
        $(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
        rm -rf *o *.mod.c *.order *.symvers

      回到T4上依旧是“Invalid module format”,但找答案的方向却是有了——找匹配的头文件,还是只有从源码中找。经过折腾,找到了在源码中产生头文件是make modules_prepare。执行后可以看到是生成了头文件的文件,但编译加载后还是“Invalid module format”,这就郁闷了,一头雾水~最后找了dmesg查看驱动加载信息的方法,dmesg后找到“”version magic '4.4.126 SMP  mod_unload aarch64' should be '.4.4.126 SMP  mod_unload modversions aarch64‘的信息,这样就可以借助强大的度娘了。于是定位到了include/linux/vermagic.h中的MODULE_VERMAGIC_MODVERSIONS,里面是个条件宏定义,一个定义成“modversions ”,一个为“”,于是将“”也改成“modversions ”,再编译,然后竟然加载成功了。激动啊,于是马上试了riffa,竟然也成功了!!!激动冷静下来后,发送不能卸载,必须sudo rmmod -f才行,而且对于hello也无法打印卸载的信息(dmesg中查看),简单查了一下,好像是内核配置打开force unload之类的选项了,应该不影响使用。由于目的是pcie的调试,所以暂时放弃深究~

      啰嗦了这么多,总结一下:

      1.安装匹配的头文件,不能install安装,就需要从源码安装,但必须保证内核版本和配置选项一致(有说在系统/proc/下有config.gz文件是系统的配置文件的,但我的系统了没有,所以只有通过官方的一些信息试——我的就是make nanopt4_linux_defconfig)

      2.可以通过dmesg查看驱动加卸载的一些信息,如果有错,这里面有很有用的信息,另外可以modinfo来查看驱动程序的一些信息,如version magic等;

      3.驱动程序的version magic很重要,其必须和内核的完全一致才能正确运行,与version magic相关的信息在uts_release.h和vermagic.h中,而且可以修改其中的值和内核一致(虽然不科学,但也不失为一种办法);

      4.源码安装头文件可以不需要编译内核,仅make defconfig && make modules_prepare即可,但需要编译内核才能生成Module.symvers,没有该文件在编译驱动时会有找不到Module.symvers的警告,但不影响驱动功能,编译内核后为节省空间又保留头文件必要的文件,可以make clean;

      5.Makefile很重要,一个正确的Makefile模板是:

obj-m:=hello.o
KDIR:=/lib/modules/$(shell uname -r)/build

PWD:=$(shell pwd)

modules:
        $(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
        rm -rf *o *.mod.c *.order *.symvers

      6.万事还是要从简单的做起,不能想着一步登天(像我最后还是从基本的hello驱动中开始)。 

你可能感兴趣的:(RK3399编译riffa续)