Linuxx 2.6内核可加载模块的编译

linux 2.6内核可加载模块的编译

allowtransparency="true" frameborder="0" height="280" hspace="0" marginwidth="0" marginheight="0" scrolling="no" vspace="0" width="336" id="aswift_0" name="aswift_0" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; left: 0px; position: absolute; top: 0px; ">
1.比较好的文章 http://blog.chinaunix.net/u2/63379/showart_526364.html 
2.A simple tourial for Linux 2.6.24 kernel module 
Author: Charles Yang <chio.yang@gmail.com> 
Linux Dist: Ubuntu 8.04 Hardy 
1. Preparation 
1.1 Download source code with apporiate version 
Usually, the linux release distribution have no full kernel source code tree. So you should get a copy of kernel source from www.kernel.org. For convience, you had better download the same version as you running linux kernel. 

You can type uname -r in you X-term, for example: 

charles@charles-laptop ~> uname -r 
2.6.24-16-generic 

1.2 Learn the document for Linux Kernel Module (LKM) 

Once you plan to do modules development, you should refer to: $SRCDIR/Document/kbuild/modules.txt 

In my ubuntu 8.04, I can find it in /usr/src/linux-headers-2.6.24-16/Documentation/kbuild 

Now let read the document for module development.. 

1). How to build external module 

From modules.txt, we know the simplest make command: 

make -C <path-to-kernel> M=`pwd` 
the <path-to-kernel> means the kernel source path. 

For the running kernel use: 

make -C /lib/modules/`uname -r`/build M=`pwd` 

The -C option: change to the directory before execute the make command. 

Actually, that will result in search the Makefile in /lib/modules/2.6.24-16-generic/build in my OS. 

Notice: Most of files in /lib/modules/2.6.24-16-generic/build actually link to /usr/src/linux-headers-2.6.24-16/ 

The M=`pwd`: define a MACRO required by Makefile in /lib/modules/2.6.24-16-generic/build, which can tell the directory of current exernal module code. 

Therefore you needn't write your own Makefile for build your modules, that's completed by kbuild - a good machism for kernel modules. 

2. make target 

make -C $KDIR M=`pwd` 
make -C $KDIR M=`pwd` all 
make -C $KDIR M=`pwd` modules 
make -C $KDIR M=`pwd` modules_install 
make -C $KDIR M=`pwd` clean 
make -C $KDIR M=`pwd` help 
the first 3 commands are absolutely same. For more details, you can refer to modules.txt 


3.Porting device drivers to the 2.6 kernel 
http://lwn.net/Articles/driver-porting/ 



4.http://www.ibm.com/developerworks/cn/linux/l-inside/index.html 
Linux 2.6的驱动程序移植 

2.6内核给驱动程序开发人员带来了一系列非常有意义的变化。本节重点介绍将驱动程序从2.4内核移植到2.6内核的一些重要方面。 

首先,相对于2.4来说,改进了内核编译系统,从而获得更快的编译速度。加入了改进的图形化工具:make xconfig(需要Qt库)和make gconfig(需要GTK库)。 

以下是2.6编译系统的一些亮点: 

当使用make时自动创建 arch-zImage 和模块 
使用 make -jN 可以进行并行的 make 
make 默认的不是冗余方式(可以通过设置 KBUILD_VERBOSE=1 或者使用 make V=1来设置为冗余方式) 
make subdir/ 将编译 subdir/ 及其子目录下的所有文件 
make help 将提供 make 目标支持 
在任何一个阶段都不需要再运行 make dep 
内核模块加载器也在2.5中完全被重新实现,这意味着模块编译机制相对于2.4有了很大不同。需要一组新的模块工具来完成模块的加载和缷载 (他们的下载链接可以在 参考资料中找到),原来的2.4所用的 makefile 在2.6下不能再用。 

新的内核模块加载器是由 Rusty Russel 开发的。它使用内核编译机制,产生一个 .ko(内核目标文件,kernel object)模块目标文件而不是一个 .o 模块目标文件。内核编译系统首先编译这些模块,并将其连接成为 vermagic.o。这一过程在目标模块创建了一个特定部分,以记录使用的编译器版本号,内核版本号,是否使用内核抢占等信息。 

现在让我们来看一个例子,分析一下新的内核编译系统如何来编译并加载一个简单的模块。这个模块是一个“hello world”模块,代码和2.4模块代码基本类似,只是 module_init 和 module_exit 要换成 init_module 和 cleanup_module (内核2.4.10模块已经使用这种机制)。这个模块命名为 hello.c,Makefile 文件如下: 


清单 3. 驱动程序 makefile 文件示例 
KERNEL_SRC = /usr/src/linux 
SUBDIR = $(KERNEL_SRC)/drivers/char/hello/ 
all: modules 
obj-m := module.o 
hello-objs := hello.o 
EXTRA_FLAGS += -DDEBUG=1 
modules: 
$(MAKE) -C $(KERNEL_SRC) SUBDIR=$(SUBDIR) modules 




makefile 文件使用内核编译机制来编译模块。编译好的模块将被命名为 module.ko,并通过编译 hello.c 和连接 vermagic 而获得。KERNEL_SRC 指定内核源文件所在的目录,SUBDIR 指定放置模块的目录。EXTRA_FLAGS 指定了需要给出的编译期标记。 

一旦新模块(module.ko)被创建,它可以被新的模块工具加载或缷载。2.4中的原有模块工具不能用来加载或缷载2.6的内核模块。这个新的模块加载工具会尽量减少在一个设备仍在使用的情况下相应的模块却被缷载的冲突发生,而是在确认这些模块已经没有任何设备在使用后再缷载它。产生这种冲突的原因之一是模块使用计数是由模块代码自己来控制的(通过MOD_DEC/INC_USE_COUNT)。 

在2.6中,模块不再需要对引用计数进行加或减,这些工作将在模块代码外部进行。任何要引用模块的代码都必须调用 try_module_get(&module),只有在调用成功以后才能访问那个模块;如果被调用的模块已经被缷载,那么这次调用会失败。相应的,可以通过使用 module_put() 来释放对模块的引用。 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值