红联Linux门户
Linux帮助

模块编程在2.4和2.6的kernel中区别

发布时间:2008-09-02 09:55:35来源:红联作者:Relief
1、模块编程在2.4和2.6的kernel中有较大的区别(下面分别给出简单实例)

(哈哈,终于调试通过了,很高兴!)

2、注意事项:

(1)、在Makefile文件中当写入命令时,应该有命令开始之前加入Tab键,否则不能通过编译!这个问题困惑了我,后来还是群里的确位仁兄指点才得已明白!

(2)、Linux里对大小写很敏感,所以在写Makefile里不要写成makefile

(3)、编程中的头文件的路径问题,要搞明白!同时要注意自己的内核是什么版的。

(4)、模块编程的例行公事:

引用:
#ifndef __KERNEL__

# define __KERNEL__

#endif

#ifndef MODULE

# define MODULE

#endif



#include

#include



#ifdef CONFIG_SMP

#define __SMP__

#endif

MODULE_LICENSE("GPL");


3、简单实例

以hello world为例:

引用:
2.4:
========================
hello.c
========================

#ifndef MODULE
#define MODULE
#endif
#ifndef __KERNEL__
#define __KERNEL__
#endif
#include
#include

int init_module(void)
{
printk(KERN_ALERT "Hello World!\n");
return 0; // Must return 0!
}

void cleanup_module(void)
{
printk(KERN_ALERT "Goodbye world!\n");
}

MODULE_LICENSE("GPL"); // Avoid "no license" warning.

========================
Makefile
========================
CC=gcc
MODCFLAGS := -I /usr/src/linux-2.4/include -DMODULE -D__KERNEL__

hello.o:hello.c
$(CC) $(MODCFLAGS) -c hello.c

.PHONY:clean

clean:
rm -f hello.o
========================

# make
# insmod hello.o
# lsmod
# rmmod hello


注:2.4的模块编程中,MODULE和__KERNEL__这两个宏必须要定义,不管你是在编译时定义还是写在源文件里。我这里是两边都写了,不过加了保护,不会出现重复定义,也不会忘记定义。linux/kernel.h这个文件中,定义了KERN_ALERT这个宏,如果你直接改写成"<1>",就可以不用包含这个头文件。而linux/module.h是模块编译必须的头文件,不可以省略。

引用:
2.6:
========================
hello.c
========================
#include
#include
#include
MODULE_LICENSE("Dual BSD/GPL");

static char *whom = "world";
module_param(whom, charp, 0);
static int howmany = 1;
module_param(howmany, int, 0);

static int hello_init(void)
{
int i;
for( i=0; i printk(KERN_ALERT "(%d) Hello, %s!\n",i,whom);
return 0;
}

static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye!\n");
}

module_init(hello_init);
module_exit(hello_exit);

========================
Makefile
========================
obj-m += hello.o

all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
========================

# make
# insmod hello.ko
或者
# insmod hello.ko howmany=2 whom=linux
# lsmod
# rmmod hello


注:在2.6中,初始化函数和收尾函数可以写成任何名字,只要在源文件中分别用module_init()和module_exit()宏调用一下就可以了,其实本质还是init_module()和cleanup_module()函数,这点你可以在/lib/modules/$(shell uname -r)/build/include/linux/init.h中看到。而在moduleparam.h中则是关于参数调用的内容。

引用:
P.S.
KERN_EMERG <0>
KERN_ALERT <1>
KERN_CRIT <2>
KERN_ERR <3>
KERN_WARNING <4>
KERN_NOTICE <5>
KERN_INFO <6>
KERN_DEBUG <7>


如果要想看到hello world的打印消息,必须切换到字符模式下,在x-window中的控制台中是收不到消息的,但是可以在/var/log/messages里看到响应的消息记录。
文章评论

共有 2 条评论

  1. 于 2012-03-15 20:27:37发表:

    受益了

  2. kinemins 于 2008-09-03 11:17:32发表:

    好帖啊!!!
    真在开始学这个。

    不过想请教init.h和module.h的绝对路径是在什么地方呢?