Chinaunix首页 | 论坛 | 博客
  • 博客访问: 256115
  • 博文数量: 65
  • 博客积分: 2599
  • 博客等级: 少校
  • 技术积分: 710
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-04 10:49
文章分类

全部博文(65)

文章存档

2015年(4)

2013年(2)

2012年(4)

2011年(51)

2010年(4)

分类: LINUX

2011-03-21 15:31:54

=== 2. 如何构建外部附加模块
构建外部附加模块需要:
1. 一个预先编译好的内核源代码树,其中必须包含(1)安装在机器上的内核的配置文件以及全套头文件
2. 内核必须允许安装模块。如果使用的是Linux发行版本,那么只要按装相应的Package即可
---2.1 命令语法
构建一个内核外部模块的语法:
$ make -C M=$PWD
只要是给出了 "M=" 选项,Kbuild系统就能够识别需要编译一个内核外部模块的需求。

在一个已经运行的内核上编译外部模块:
$ make -C /lib/modules/`uname -r`/build M=$PWD
然后安装刚刚编译的模块,在Makefile中添加target "modules_install",或者使用命令行
$ make -C /lib/modules/`uname -r`/build M=$PWD modules_install
--- 2.2 选项
($KDIR 指向内核源代码所在的目录)
make -C $KDIR M=$PWD

-C $KDIR
指名内核源代码所在的目录。make在执行的时候会自动转向这个目录进行
编译和链接,之后会自动转回当前目录。
-M=$PWD
告知kernel有一个外部模块在进行构建。给"-M"选项的值必须是一个绝对路径,
这个路径指向外部模块的所在的目录。

--- 2.3 Targets
当构建一个外部模块的时候,只有一部分make的target可以使用。

make -C $KDIR M=$PWD [target]
默认情况下会构建当前目录中的模块,所以只有一个模块目标的时候,
不需要显示的指定。所有的输出文件也会存在于这个当前目录中。编译
外部模块的时候运行的make不会企图更新内核源代码,但是必须保证在
构建模块的时候,kernel已经事先构建好了。(这种情况会出现在,将
模块编译到一个没有正在运行的kernel source中的情况)
可以使用的target列表:
1. modules:
外部模块的默认目标。显示指定它的效果和没有指名任何target的效果一样。
2. modules_install:
安装外部模块。默认的安装路径是/lib/modules//extra/,
但是或许应该添加一个前缀,使用变量 INSTALL_MOD_PATH。
3. clean:
删除所有的生成文件,包括目标和中间输出文件。
4. help:
列出全部的可用的外部模块target

--- 2.4 当有多个分离的文件时的构建
可以从多个单独的文件构建模块。这对于kernel,外部模块,模块来说
是等价的。

Example (The module foo.ko, consist of bar.o and baz.o):
make -C $KDIR M=$PWD bar.lst
make -C $KDIR M=$PWD baz.o
make -C $KDIR M=$PWD foo.ko
make -C $KDIR M=$PWD /
=== 3. 为外部模块构建Kbuild文件

上面所看到的命令并不能构建一个完整的模块,因为Linux Kernel强制要求
一个Kbuild文件。这个文件中应该包含:模块的名字,以及模块所以来的源文件。
只要简单的加上下面一行就可以:
obj-m := .o
Kbuild系统会根据 .c来构建.o,然后通过连接构建
.ko。上面的这一行写在文件名为 "Kbuild" 或者 "Makefile"的文件中
都可以。如果需要多源文件,那么需要添加下面这一行:
-y := .o .o ...
/* 第三部分略过 */

=== 4. 引用头文件

在Kernel中,头文件都包含在标准的目录中,遵循下面的规则:
* 如果头文件只是描述模块内部的接口,那么它应该和源文件方在一起。 
* 如果头文件描述了供其他内核模块调用的接口,那么应该将其放在
 include/linux/目录中。

--- 4.1 引用kernel头文件

简单的使用include即可,Kbuild会将引用信息传递给gcc。
#include

--- 4.2 单独的子目录
外部模块更倾向于将头文件放在自己所在目录下的include目录中。虽然,
这并不是内核的一贯组织文件方式,但是可以通过 ccflags-y := -I
或者 CFLAGS_.o来通知Kbuild系统。

例如:
ccflags-y := -Iinclude
注意,-I和之间没有空格。

--- 4.3 多个子目录的情况

Kbuild能够处理多个文件存在多个子目录的情况。
举例:/* 文件组织如下 */
.
|__ src
|   |__ complex_main.c
|   |__ hal
| |__ hardwareif.c
| |__ include
|    |__ hardwareif.h
|__ include
   |__ complex.h

为了构建模块complex.ko,我们需要如下的kbuild文件
kbuild file:

--> filename: Kbuild
obj-m := complex.o
complex-y := src/complex_main.o
complex-y += src/hal/hardwareif.o

ccflags-y := -I$(src)/include
ccflags-y += -I$(src)/src/hal/include
kbuild可以处理多个目标文件存在于多个单独的目录的情况,
解决的方法是通过提供一个或者多个相对于kbuild文件
所在目录的相对路径。但是不建议这样作!!!

对于头文件(.h)来说,kbuild必须要的到文件的绝对路径才能够找到头文件!
因为当kbuild运行的时候,当前路径是kernel tree所在的路径(-C 参数的作用)。
$(src)必须提供一个绝对路径,指向编译模块的kbuild文件所在的目录。


阅读(1177) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~