代码本身非常简单,就是万能例子hello world
#include </linux/modules.h>
#include </linux/init.h>
int hello_init(void)
{
printk("hello world!");
return 0;
}
void hello_exit(void)
{
printk("Goodbye!");
}
module_init(hello_init);
module_exit(hello_exit);
在最近安装的redhat 6上用gcc hello.c -o hellomod.o编译,结果报modules.h和init.h找不到。
上网百度找答案,有说是linux内核代码没有安装,有这两个头文件的路径错了。应该在/urs/src/kernel/2.6.*****/include/linux下。
按这两种说查找原因,发现源代码是有的。而且即使将头文件路径修改成上面的路径,编译时会报一大堆其他的错误。
然后在网上找到了第三种说法,即需要用makefile来编译。于是拷贝网上的makefile脚本并命名Makefile,然后执行make命令,发现成功了。
程序代码路径下生成了好几个文件。
试着用模块装载命令insmod去装载模块,结果提示不是可用的模块,继续百度找原因,最后确定是insmod命令的目标模块参数错了,我把hellomod.o成了
模块,其实最终的模块是hellomod.ko
俗话说得好,看着简单,做起来就知道难了。
一个简单的模块代码花了我整整一天时间。而且虽然成功了,但却依然有两个疑问没有解决:
1. 是不是模块编译只能用makefile,如果不是那么怎么用gcc命令替代,用-l选项吗?
2. 如果是,那么makefile中脚本具体是什么含义?makefile又该如何编写呢?
对于上面两个问题,尤其是第一个,希望有高手能指点一下迷津。
(后续)
高手最终还是自己。
其实makefile只是make的一个执行脚本,而make最终还是调用gcc来编译模块的。
可以通过在make 后面添加V=1命令参数来查看最终执行的命令是什么。
你可以发现,除了gcc命令还有很多诸如宏等各种命令内容。这些东西反正我是不太愿意去具体了解到底是什么东西。
那这些命令怎么来的呢?
肯定不是make自动生成的。这些命令其实都归根于一个叫kbuild的东西。
kBuild 是一个编译框架, 它基于修改过的GNU make工具和一系列标准的跨平台工具。kBuild 相当的强大,它尽力将它的大部分复杂性隐藏在模板中,
因而实际的makefiles就变的相对易懂并容易编写。 然而kBuild的核心十分的复杂,目前地球上只有0.5个人能够完全弄懂它。:-),有兴趣和信心的朋友
可以尝试一下成为另外一个0.5人。
kbuild其实也是linux2.4和2.6编译方式的不同之处。2.6是采用kbuild框架,因此网上会有2.6必须要用makefile编译模块的说法。
至于第二个问题,makefile怎么写,自己在网上倒腾了一阵,找到一本经典的书《Makefile经典教程》。这个在百度文档上有。
具体如何写让我先浏览浏览这本书。