当前位置: 首页 > 科技观察

驱动编译相关的三类文件:Makefile、Config、Kconfig

时间:2023-03-21 15:05:22 科技观察

赵庆尧审稿人|孙淑娟在开发驱动的时候,有时候最让我们头疼的不是驱动代码的编写,而是代码的编译。目前有很多同事向我反映,修改了相应的Config和Makefile文件,但是仍然无法正常编译驱动。经查,这个问题是没有修改相应的Kconfig导致的。在这篇文章中,我将主要讲解如何修改驱动编译相关的Makefile、Config和Kconfig这三类文件,并简单说明三者之间的关系。1.如何修改这三类文件来编译我们的驱动生产文件我们可以使用Makefile来编写驱动编译的规则。下面是四种常见且比较简单的编译规则。这里如果我们的驱动文件是test.c,默认包含了需要的库、头文件等,这里只说明Makefile、config和Kconfig的关系。但是解释一下Makefile的更多细节:obj–y+=test.oobj-n+=test.oobj-m+=test.oobj-($CONFIG_TEST)+=test.oobj-y表示test.c需要编译进入Kernel,当我们不知道如何配置config和Kconfig,或者配置后驱动无法编译时,可以使用这种配置方式。这种方式的好处是在Makefile中只写规则,Makefile可以被编译系统加载,相应的驱动不再受config和Kconfig的约束,可以编译进内核.obj-n表示默认不编译,这个配置几乎没用过。毕竟一般情况下,我们是不会写出编译不通过的代码的。但是,当多个项目或多个平台重用代码时,可能会根据项目或平台编译选项。这时候不需要编译的代码可以通过obj-n的方式进行配置。obj-m表示默认编译为模块,需要注意的是在执行make模块时会编译。当发现驱动没有被编译时,可以通过执行make模块检查是否使用了obj-m并进行了编译。obj-($CONFIG_TEST),我调用这个方法条件编译,根据CONFIG_TEST的配置进行编译,我们可以在项目对应的config中将CONFIG_TEST配置为m、y或n,这样obj-($CONFIG_TEST)就可以变成obj-m,obj-y,obj-n。通常以obj-($CONFIG_TEST)+=test.o的方式配置。实际上,配置文件分为两类。这里我以kernel-4.19和arm平台为例进行说明。其中一类位于kernel-4.19/arch/arm/configs,另一类是隐藏文件,位于kernel-4.19/.config路径下,两类文件格式相同,如图下图:从上图可以看出,这类文件定义了一些配置项,Makefile部分提到的CONFIG_TEST需要在config文件Configure中。使用文件kernel-4.19/arch/arm/configs配置时,比较简单。直接打开对应的config文件,添加CONFIG_TEST=(y/n/m)。在使用kernel-4.19/.config配置时,建议不要直接修改.config文件,而是通过makemenuconfig进行配置,后面会介绍。在编译Linux内核时,驱动是根据.config文件结合Makefile编译的,kernel-4.19/arch/arm/configs会通过其对应的make命令生成对应的.config。想象一下,此时如果我们的kernel-4.19/arch/arm/configs和.config都配置了CONFIG_TEST,那CONFIG_TEST最终会采用什么样的配置呢?其实kernel-4.19/arch/arm/configs下的配置会覆盖.config中的配置,所以我个人喜欢直接修改kernel-4.19/arch/arm/configs。但是当kernel-4.19/arch/arm/configs中没有配置CONFIG_TEST时,Kconfig中配置的CONFIG_TEST会作为.config中的默认值。这里Kconfig还是以CONFIG_TEST为例进行说明。Kconfig中有两个地方需要修改。一种是test.c对应的Kconfig文件,一种是包含Kconfig文件。下面是对应的Kconfig配置方法。第一行的configTEST对应config中的CONFIG_TEST。注意Kconfig中需要去掉CONFIG,只配置为TEST;第二行的三态表示该项是否被编译进内核。或者编译成模块,如果把第二行的三态改成bool,可以配置test.c是否编译进内核,但是不能以模块的形式编译;第三行设置默认值,即默认编译进内核;第四行是说明信息。configTESTtristate"THISISTESTDRIVER"defaultyhelpthisisjustfortest当我们配置Kconfig时,我们需要将Kconfig包含到系统中。如果Kconfig位于路径drivers/input/test/下,则可以使用语句源“drivers/input/test/Kconfig”包含Kconfig文件。2、Makefile、Config、Kconfig的关系切入内核的方法之一是使用命令makemenuconfig,它会获取Kconfig的信息,然后以下图的形式从终端显示出来。上图类似于我们在餐厅看到的菜单,所以我们可以把Kconfig比作菜单,Makefile比作菜谱,config比作我们点的菜,makemenuconfig来显示菜单命令。我们写好驱动代码后,还需要写一个recipe,将驱动添加到menu中,然后通过config或者makemenuconfig命令,这样就可以正常编译驱动了。3、常见错误常见的错误有两种:只点菜和菜谱配置,却忘记在菜单中添加菜名,导致编译驱动失败;排序时使用错误的语法格式,有些程序员由于写代码的习惯,等号两边通常会保留空格,但在使用config排序时,等号两边不能有空格。4.小结本文主要介绍驱动编译需要配置的三类文件:Makefile、Kconfig、config。希望驱动开发者在掌握了这些内容后,在开发过程中能够将注意力集中在驱动本身,而不是将时间浪费在编译部分。作者介绍社区编辑赵庆尧,从事驱动开发多年。他的研究兴趣包括安全操作系统和网络安全,并发表了与网络相关的专利。