Chinaunix首页 | 论坛 | 博客
  • 博客访问: 365601
  • 博文数量: 104
  • 博客积分: 2519
  • 博客等级: 少校
  • 技术积分: 1025
  • 用 户 组: 普通用户
  • 注册时间: 2008-09-22 06:54
文章分类

全部博文(104)

文章存档

2009年(90)

2008年(14)

我的朋友

分类: LINUX

2008-11-14 19:11:56

1.比较好的文章 http://blog.chinaunix.net/u2/63379/showart_526364.html
2.A simple tourial for Linux 2.6.24 kernel module
Author: Charles Yang <>
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  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 M=`pwd`
the 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


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 文件如下:



           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() 来释放对模块的引用。 


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