如何编译linux驱动模块

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

首先,我们要了解一下模块是如何别被构造的。模块的构造过程与用户空间的应用程序的构造过程有显著不同;内核是一个大的、独立的程序,对于它的各个部分如何组合在一起有详细的明确的要求。Linux2.6内核的构造过程也与以前版本的内核构造过程不同;新的构造系统用起来更加简单,并且可产生更加正确的结果,但是它看起来和先前的方法有很大不同。内核的构造系统非常复杂,我们所看到的只是它的一小部分。如果读者想了解更深入的细节,则应阅读在内核源码中的Document/kbuild目录下的文件。

在构造内核模块之前,有一些先决条件首先应该得到满足。首先,读者要保证你有适合于你的内核版本的编译器、模块工具,以及其他必要工具。在内核文档目录下的文件Documentation/Changes里列出了需要的工具版本;在开始构造内核前,读者有必要查看该文件,并确保已安装了正确的工具。如果用错误的工具版本来构造一个内核(及其模块),可能导致许多奇怪的问题。另外也要注意,使用太新版本的编译器偶尔可能也会导致问题。

一旦做好了上面的准备工作之后,其实给自己的模块创建一个makefile则非常简单。实际上,对于本章前面展示的" hello world"例子,下面一行就够了: obj-m := hello.o

如果读者熟悉make,但是对Linux2.6内核构造系统不熟悉的话,可能奇怪这个makefile如何工作。毕竟上面的这一行不是一个传统的makefile的样子。问题的答案当然是内核构造系统处理了余下的工作。上面的赋值语句(它利用了由GNU make提供的扩展语法)说明有一个模块要从目标文件hello.o构造,而从该目标文件构造的模块名称为hello.ko.

如果我们想由两个源文件(比如file1.c和file2.c )构造出一个名称为module.ko的模块,则正确的makefile可如下编写:

obj-m := module.o

module-objs := file1.o file2.o

为了让上面这种类型的makefile文件正常工作,必须在大的内核构造系统环境中调用他们。假设读者的内核源码数位于~/kernel-2.6目录,用来建立你的模块的make命令(在包含模块源代码和makefile的目录下键入)应该是:

make -C ~/kernel-2.6 M=`pwd` modules

这个命令首先是改变目录到用-C选项指定的位置(即内核源代码目录),其中保存有内核的顶层makefile文件。这个M=选项使makefile在构造modules目标前,返回到模块源码目录。然后,modules目标指向obj-m变量中设定的模块,在上面的例子里,我们将该变量设置成了module.o。

上面这样的make命令对于多个文件的编译显得不是很方便,于是内核开发者就开发了一种makefile方式,这种方式使得内核树之外的模块构造变得更加容易。代码清单1.4展示了makefile的编写方法:

代码清单1.4 makefile

ifeq ($(KERNELRELEASE),)

KERNELDIR ?= /source/linux-2.6.13

PWD := $(shell pwd)

modules:

$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

modules_install:

$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

clean:

rm -rf *.o *~ core .depend .*. *.ko *.mod.c .tmp_versions .PHONY: modules modules_install clean

else

obj-m := hello.o

endif

我们再次看到了扩展的GNU make语法在起作用。在一个典型的构造过程中,这个makefile将被读取两次。当从命令行中调用这个makefile ,它注意到KERNELRELEASE变量尚未设置。我们可以注意到,已安装的模块目录中存在一个符号连接,它指向内核的构造树,这样这个makefile就可以定位内核的源代码目录。如果读者时间运行的内核并不是要构造的内核,则可以在命令行提供KERNELDIR=选项或者设置KERNELDIR环境变量,或者修改makefile中设置KERNELDIR的那一行。在找到内核源码树,这个makefile会调用default:目标,这个目标使用先前描述过的方法第二次运行make命令(注意,在这个makefile里make命令被参数化成$(MAKE)),以便运行内核构造系统。在第二次读取makefile时,它设置了obj-m,而内核的makefile负责真正构造模块。这种构造模块的机制看起来很繁琐,可是,一旦我们习惯了使用这种机制,则会欣赏内核构造系统带给我们的便利。需要注意的是,上面makefile并不完整,一个真正的makefile应包含通常用来清除无用文件的目标,安装模块的目标等等。一个完整的例子可以参考例子代码目录的makefile。

相关文档
最新文档