Hello World 模块以及对应的内核makefile详解
2014-09-22 11:13
375 查看
hello.c:
#include <linux/module.h>
//所有模块都需要的头文件
#include <linux/init.h>
// init&exit相关宏
MODULE_LICENSE("GPL");
MODULE_AUTHOR("feifei");
MODULE_DESCRIPTION("hello
world module");
static int __init
hello_init(void){
printk(KERN_ERR "hello
world");
return 0;
}
static void __exit hello_exit(void){
printk(KERN_EMERG "hello
exit!");
}
module_init(hello_init);
module_exit(hello_exit);
/*注释:这个模块定义了两个函数, 一个在模块加载到内核时被调用( hello_init )以及一个在模块被去除时被调用( hello_exit ).
moudle_init 和 module_exit 是比较特别的内核宏来指出这两个函数的角色
宏 (MODULE_LICENSE) 是用来告知内核, 该模块带有一个自由的许可证; 没有这样的说明, 在模块加载时内核会抱怨
printk 函数在 Linux 内核中定义并且对模块可用;
它与标准 C 库函数 printf 的行为相似. 内核需要它自己的打印函数, 因为它靠自己运行, 没有
C 库的帮助.
字串 KERN_EMERG 是消息的优先级,可以用 <1>,等对应的数字代替来前缀于
printk 格式串之前. 注意如果用
KERN_ALERT ,之后要缺少一个逗号
*/
Makefile:
ifneq ($(KERNELRELEASE),)
obj-m :=hello.o
else
KDIR :=/lib/modules/&(shell
uname -r)/build
all:
make -C
$(KDIR) M=$(PWD) modules
clean:
make -C
$(KDIR) M=$(PWD) clean
endif
~
/*注释:
上面的这一行不是一个传统的 makefile 的样子,是kbuild
makefile语法
obj-m :=hello.o表明有一个模块要从目标文件
hello.o
建立. 在从目标文件建立后结果模块命名为
hello.ko
扩展一点: 如果你有一个模块名为 module.ko, 是来自
2 个源文件( 姑且称之为, file1.c
和 file2.c ), 正确的书写应当是:
obj-m := module.o
module-objs := file1.o
file2.o
make -C
$(KDIR):这个命令开始是改变它的目录到用 -C
选项提供的目录下( 就是说, 你的内核源码目录 )
它在那里会发现内核的顶层 makefile。
这个 M= 选项使
makefile 在试图建立模块目标前, 回到你的模块源码目录。
M=$(PWD) 作为参数传给Makefile,内核中的解释是:make
M=dir
modules Make all modules in specified
dir
目标, 是指在
obj-m
变量中发现的模块列表, 在我们的例子里设成了
hello.o
&(shell
uname -r):是调用shell命令,在我系统上是2.6.18-92.el5,所以KDIR :=/lib/modules/&(shell
uname -r)/build:
/lib/modules/2.6.18-92.el5/build/是内核源码.
内核源码Makefile中350行有关于KERNELRELEASE定义:
#KERNELRELEASE = $(shell
cat include/config/kernel.release
2> /dev/null)
下面,全面的解释一下这个makefile的执行流程:
这个 makefile 在一次典型的建立中要被读 2 次. 在第一次读取执行此Makefile时,KERNELRELEASE没有被定义,
所以make将读取执行else之后的内容,如果make的目标是clean,直接执行clean操作,然后结束。当make的目标为all时,
-C
$(KDIR)指明跳转到内核源码目录下读取那里的Makefile;M=$(PWD) 表明然后返回到当前目录继续读入、
执行当前的Makefile。当从内核源码目录返回时,KERNELRELEASE已被定义,kbuild也被启动去解析kbuild语法的语句,
make将继续读取else之前的内容。else之前的内容为kbuild语法的语句,指明模块源码中各文件的依赖关系,以及要生成的目标模块名。
obj-m := hello.o表示编译连接后将生成param.ko模块。
这种建立模块的机制你可能感觉笨拙模糊. 一旦你习惯了它, 但是, 你很可能会欣赏这种已经编排进内核建立系统的能力.
注意, 上面的不是一个完整的
makefile; 一个真正的
makefile 包含通常的目标类型来清除不要的文件,
安装模块等等. 一个完整的例子可以参考例子代码目录的
makefile.
*/
三。加载模块
[root]# ls
hello.c
hello.mod.c
hello.o
Module.markers
Module.symvers
hello.ko
hello.mod.o
Makefile modules.order
root# insmod hello.ko
Hello, world
root# rmmod hello
hello exit!
#include <linux/module.h>
//所有模块都需要的头文件
#include <linux/init.h>
// init&exit相关宏
MODULE_LICENSE("GPL");
MODULE_AUTHOR("feifei");
MODULE_DESCRIPTION("hello
world module");
static int __init
hello_init(void){
printk(KERN_ERR "hello
world");
return 0;
}
static void __exit hello_exit(void){
printk(KERN_EMERG "hello
exit!");
}
module_init(hello_init);
module_exit(hello_exit);
/*注释:这个模块定义了两个函数, 一个在模块加载到内核时被调用( hello_init )以及一个在模块被去除时被调用( hello_exit ).
moudle_init 和 module_exit 是比较特别的内核宏来指出这两个函数的角色
宏 (MODULE_LICENSE) 是用来告知内核, 该模块带有一个自由的许可证; 没有这样的说明, 在模块加载时内核会抱怨
printk 函数在 Linux 内核中定义并且对模块可用;
它与标准 C 库函数 printf 的行为相似. 内核需要它自己的打印函数, 因为它靠自己运行, 没有
C 库的帮助.
字串 KERN_EMERG 是消息的优先级,可以用 <1>,等对应的数字代替来前缀于
printk 格式串之前. 注意如果用
KERN_ALERT ,之后要缺少一个逗号
*/
Makefile:
ifneq ($(KERNELRELEASE),)
obj-m :=hello.o
else
KDIR :=/lib/modules/&(shell
uname -r)/build
all:
make -C
$(KDIR) M=$(PWD) modules
clean:
make -C
$(KDIR) M=$(PWD) clean
endif
~
/*注释:
上面的这一行不是一个传统的 makefile 的样子,是kbuild
makefile语法
obj-m :=hello.o表明有一个模块要从目标文件
hello.o
建立. 在从目标文件建立后结果模块命名为
hello.ko
扩展一点: 如果你有一个模块名为 module.ko, 是来自
2 个源文件( 姑且称之为, file1.c
和 file2.c ), 正确的书写应当是:
obj-m := module.o
module-objs := file1.o
file2.o
make -C
$(KDIR):这个命令开始是改变它的目录到用 -C
选项提供的目录下( 就是说, 你的内核源码目录 )
它在那里会发现内核的顶层 makefile。
这个 M= 选项使
makefile 在试图建立模块目标前, 回到你的模块源码目录。
M=$(PWD) 作为参数传给Makefile,内核中的解释是:make
M=dir
modules Make all modules in specified
dir
目标, 是指在
obj-m
变量中发现的模块列表, 在我们的例子里设成了
hello.o
&(shell
uname -r):是调用shell命令,在我系统上是2.6.18-92.el5,所以KDIR :=/lib/modules/&(shell
uname -r)/build:
/lib/modules/2.6.18-92.el5/build/是内核源码.
内核源码Makefile中350行有关于KERNELRELEASE定义:
#KERNELRELEASE = $(shell
cat include/config/kernel.release
2> /dev/null)
下面,全面的解释一下这个makefile的执行流程:
这个 makefile 在一次典型的建立中要被读 2 次. 在第一次读取执行此Makefile时,KERNELRELEASE没有被定义,
所以make将读取执行else之后的内容,如果make的目标是clean,直接执行clean操作,然后结束。当make的目标为all时,
-C
$(KDIR)指明跳转到内核源码目录下读取那里的Makefile;M=$(PWD) 表明然后返回到当前目录继续读入、
执行当前的Makefile。当从内核源码目录返回时,KERNELRELEASE已被定义,kbuild也被启动去解析kbuild语法的语句,
make将继续读取else之前的内容。else之前的内容为kbuild语法的语句,指明模块源码中各文件的依赖关系,以及要生成的目标模块名。
obj-m := hello.o表示编译连接后将生成param.ko模块。
这种建立模块的机制你可能感觉笨拙模糊. 一旦你习惯了它, 但是, 你很可能会欣赏这种已经编排进内核建立系统的能力.
注意, 上面的不是一个完整的
makefile; 一个真正的
makefile 包含通常的目标类型来清除不要的文件,
安装模块等等. 一个完整的例子可以参考例子代码目录的
makefile.
*/
三。加载模块
[root]# ls
hello.c
hello.mod.c
hello.o
Module.markers
Module.symvers
hello.ko
hello.mod.o
Makefile modules.order
root# insmod hello.ko
Hello, world
root# rmmod hello
hello exit!
相关文章推荐
- Hello World 模块以及对应的内核makefile详解
- linux 2.6内核 编译模块Makefile 详解
- Helloworld模块之内核makefile详解
- linux 2.6内核 编译模块Makefile 详解!
- linux 2.6内核 编译模块Makefile 详解
- 内核模块的基本编写以及Makefile的编写
- 内核模块多文件makefile
- 内核sanitize_e820_map函数详解(征服内存管理模块的起点)
- 如何导出内核模块符号以及如何引用导出的符号
- Linux 编译内核模块的Makefile
- linux2.4与2.6内核模块的Makefile模版
- 2.6 内核模块的Makefile模板
- Linux 内核模块编程 Hello World 模块
- 在Linux下编译内核模块的Makefile的几种写法 转
- 两个编译2.4与2.6内核模块的Makefile 模板
- linux2.6内核Makefile详解
- linux 2.6 内核模块的Makefile
- 写内核模块Makefile的技巧
- Linux 内核模块之hello world
- linux 第一个内核模块Hello World