#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 中所列出的檔案用來組成該目錄下的一個庫檔案。