1. 程式人生 > >模組-kernel 模組編譯(Makefile編寫)

模組-kernel 模組編譯(Makefile編寫)

發現自己以前寫的2.4的模組無法在2.6下面編譯使用了,需要用新的Makefile才行。簡單的說就像這個樣子:                                            
                                                                                                                                            
    obj-m := mytest.o                                                                                                                       
                                                                                                                                            
    KDIR := /lib/modules/$(shell uname -r)/build                                                                                            
                                                                                                                                            
    PWD := $(shell pwd)                                                                                                                     
                                                                                                                                            
    default:                                                                                                                                
                                                                                                                                            
     $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules                                                                                              
                                                                                                                                            
                                                                                                                                            
                                                                                                                                            
    就可以了,模組的名稱是mytest,最後編譯出來是mytest.ko,剩下的系統搞定。當然這裡有一些隱含規則了,就是mytest.o由                         
                                                                                                                                            
    mytest.c或者mytest.S編譯出來。如果模組是由多個原始檔搞定的,那麼建議去參考                                                              
                                                                                                                                            
    ~linuxsrc/Documentation/kbuild/下的一些文件。                                                                                           
                                                                                                                                            
    --- add on 2005年11月16日 ---                                                                                                           
                                                                                                                                            
    如果是多個原始檔編譯出一個模組,那麼假設模組名是mytest.ko,那麼原始檔名不能有mytest.c,下面是一個例子:                                 
                                                                                                                                            
    obj-m := mytest.o                                                                                                                       
                                                                                                                                            
    mytest-objs := file1.o file2.o file3.o                                                                                                  
                                                                                                                                            
    KDIR := /lib/modules/$(shell uname -r)/build                                                                                            
                                                                                                                                            
    PWD := $(shell pwd)                                                                                                                     
                                                                                                                                            
    default:                                                                                                                                
                                                                                                                                            
     $(MAKE) -C $(KDIR) M=$(PWD) modules                                                                                                    
                                                                                                                                            
    這裡比較奇怪的是makefile裡面沒有用SUBDIRS=,而是用了M=                                                                                  
                                                                                                                                            
    --- end of add on 2005年11月16日 ---                                                                                                    
                                                                                                                                            
    --- add on 2006年5月20日 ---                                                                                                            
                                                                                                                                            
    關於前面的makefile當中用M=代替SUBDIR=,效果是一樣的,但是M=更明確,參見《從 2.4 到 2.6:Linux 核心可裝載模組機制的改變對裝置驅動的影響》
                                                                                                                                            
    http://www-128.ibm.com/developerworks/cn/linux/l-module26/                                                                              
                                                                                                                                            
    對於Makefile,其中建議為(將上面的改成):                                                                                              
                                                                                                                                            
    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模組。                                                                                              
                                                                                                                                            
    --- end of add on 2006年5月20日 ---                                                                                                     
                                                                                                                                            
     另外,編譯完核心以後用make INSTALL_MOD_PATH=/pathyouwant modules_install可以把核心模組裝到指定目錄