#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int hello_init(void)
{
printk("....\n");
return 0;
}
static void hello_exit()
{
printk("...");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("Dual BSD/GPL);
Makefile文件:
obj-m := test.o
KDIR := /lib/modules/$(shell uname -r)/build $(KDIR)指定了內核源碼的路徑,"M="表示這是個外部模塊,M=$(PWD) 指定了該模塊文件所在的路徑。
PWD :=$(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -rf *.ko
rm -rf *.mod.*
rm -rf .*.cmd
rm -rf *.o
insmod test.ko,rmmod test.ko
如果是多個源文件編譯出一個模塊,假設模塊名是test.ko,那麼源文件名不能有test.c。注:2.6下編譯模塊的詳細方法請參考linux/Documentation/kbuild/modules.txt。
ifneq ($(KERNELRELEASE),)
obj-m := mytest.o
mytest-objs := file1.o file2.o file3.o
else
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
endif
解釋爲:
KERNELRELEASE
是在內核源碼的頂層Makefile中定義的一個變量,在第一次讀取執行此Makefile時,KERNELRELEASE沒有被定義,
所以make將讀取執行else之後的內容。如果make的目標是clean,直接執行clean操作,然後結束。當make的目標爲all時,-C
$(KDIR) 指明跳轉到內核源碼目錄下讀取那裏的Makefile;M=$(PWD)
表明然後返回到當前目錄繼續讀入、執行當前的Makefile。當從內核源碼目錄返回時,KERNELRELEASE已被被定義,kbuild也被啓動去
解析kbuild語法的語句,make將繼續讀取else之前的內容。else之前的內容爲kbuild語法的語句,
指明模塊源碼中各文件的依賴關係,以及要生成的目標模塊名。mytest-objs := file1.o file2.o
file3.o表示mytest.o 由file1.o,file2.o與file3.o 連接生成。obj-m :=
mytest.o表示編譯連接後將生成mytest.o模塊。
Linux內核的Makefile分爲5個部分:
Makefile 頂層Makefile
.config 內核配置文件
arch/$(ARCH)/Makefile 具體架構的Makefile
scripts/Makefile.* 通用的規則等。面向所有的Kbuild Makefiles。
kbuild Makefiles 內核源代碼中大約有500個這樣的文件
頂層Makefile閱讀的.config文件,而該文件是由內核配置程序生成的。
頂層Makefile負責製作:vmlinux(內核文件)與模塊(任何模塊文件)。製作的過程主要是
通過遞歸向下訪問子目錄的形式完成。並根據內核配置文件確定訪問哪些子目錄。頂層
Makefile要原封不動的包含一具體架構的Makefile,其名字類似於 arch/$(ARCH)/
Makefile。該架構Makefile向頂層Makefile提供其架構的特別信息。
每一個子目錄都有一個Kbuild Makefile文件,用來執行從其上層目錄傳遞下來的命令。
Kbuild Makefile從.config文件中提取信息,生成Kbuild完成內核編譯所需的文件列表。
scripts/Makefile.*包含了所有的定義、規則等信息。
目標定義是Kbuild Makefile的主要部分,也是核心部分。主要是定義了要編譯的文件,所有的選項,以及到哪些子目錄去執行遞歸操作。
最簡單的Kbuild makefile 只包含一行:
例子:
obj-y += foo.o
該例子告訴Kbuild在這目錄裏,有一個名爲foo.o的目標文件。foo.o將從foo.c或foo.S文件編譯得到。
如果foo.o要編譯成一模塊,那就要用obj-m了。所採用的形式如下:
例子:
obj-$(CONFIG_FOO) += foo.o
$(CONFIG_FOO)可以爲y(編譯進內核) 或m(編譯成模塊)。如果CONFIG_FOO不是y和m,那麼該文件就不會被編譯聯接了
Kbuild能夠識別用於組成目標文件的後綴-objs和後綴-y。這就讓Kbuild Makefile可以通過使用 CONFIG_ 符號來判斷該對象是否是用來組合對象的。
在 obj-* 中所列文件是用來編譯模塊或者是聯接到特定目錄中的 built-in.o。同樣,也可以列出一些將被包含在lib.a庫中的文件。在 lib-y 中所列出的文件用來組成該目錄下的一個庫文件。