編寫模組時一般都需要包含標頭檔案,而在module.h中定義了符號__module_kernel_version
static const char __module_kernel_version __attribute__((section(".modinfo"))) =
"kernel_version=" uts_release;
#define uts_release "2.4.18-rmk7-pxa1" //include/linux/version.h
符號__module_kernel_version在編譯後被放在.o檔案的.modinfo段,in**od使用它檢查模組和當前核心版本是否匹配.
看到《linux裝置驅動程式2》中所說的如果把模組**分為兩塊,則需要在另乙個檔案包含module.h前定義__no_version__ 使得不再重複定義__module_kernel_version,不過在我的源**裡並沒什麼用,在我的module.h並沒有這種條件包含,而且編譯也不會出錯,只是用objdump工具察看時,確實在.modinfo出現了兩個__module_kernel_version符號。objdump -s hello.o
下面是乙個makefile檔案
cc = /opt/host/armv4l/bin/armv4l-unknown-linux-gcc
ld = /opt/host/armv4l/bin/armv4l-unknown-linux-ld
cflags = -d__kernel__ -dmodule -i/hharm2410-r3/kernel/include -wall -wstrict-prototypes -wno-trigraphs -os -mapcs -fno-strict-aliasing -fno-common -fno-common -pipe -mapcs-32 -march=armv4 -mtune=arm9tdmi -mshort-load-bytes -msoft-float -i/opt/host/armv4l/src/linux/include
all: hello.o
hello.o: start.o stop.o
$(ld) -r $^ -o $@
.phony: clean
clean:
-rm -f *.o
當然是我的arm平台的,注意cflags,-d__kernel__ -dmodule就相當於在每個檔案中define了__kernel__和module這兩個巨集,還要用-i包含核心原始碼的include目錄.
另外來分析一下模組經常用到的一些巨集
第乙個是 this_module,一開始就知道是直向模組自身,但是還是深入研究下吧
在module.h中尋找this_module的定義
#if defined(module) && !defined(__genksyms__)
extern struct module __this_module;
#define this_module (&__this_module)
#else
#ifndef __genksyms__
#define this_module null
#endif
#endif
一般不會定義__genksyms__,而編寫模組都會定義module,
所以this_module是乙個struct module型別的指標。
我們把模組編譯成乙個.o目標檔案,其實並沒有進行其中的呼叫進行鏈結,顯然真正的鏈結過程發生在我們把模組in**od的核心時,而在in**od時核心會建立乙個struct module結構的結構體來包容從使用者空間load進來的模組,在鏈結的時候就會把這個指標給this_module.
下面這些巨集就是在.modinfo段定義乙個字串,沒什麼可說的。
#define module_author(name) /
const char __module_author __attribute__((section(".modinfo"))) = /
"author=" name
#define module_description(desc) /
const char __module_description __attribute__((section(".modinfo"))) = /
"description=" desc
下面幾個巨集會比較複雜
#define mod_inc_use_count __mod_inc_use_count(this_module)
#define mod_dec_use_count __mod_dec_use_count(this_module)
#define mod_in_use __mod_in_use(this_module)
#define __mod_inc_use_count(mod) /
(atomic_inc(&(mod)->uc.usecount), (mod)->flags |= mod_visited|mod_used_once)
#define __mod_dec_use_count(mod) /
(atomic_dec(&(mod)->uc.usecount), (mod)->flags |= mod_visited)
#define __mod_in_use(mod) /
(mod_member_present((mod), can_unload) && (mod)->can_unload /
? (mod)->can_unload() : atomic_read(&(mod)->uc.usecount))
不過理解了this_module看起來就是比較簡單了,顯然struct module中有對模組使用進行計數的乙個變數,我們可以編寫簡單的模組來列印當前模組結構變數的值
union
uc;
mod_inc_use_count就是讓usecount加1,mod_dec_use_count讓usecount減1
mod_in_use挺複雜,想繼續理解就自己繼續學習吧。。。編寫簡單的模組測試比較eazy吧
Linux 核心巨集 container of
container of ptr,type,member arguments ptrthe pointer to the member.代表指標 type the type ofthe container struct this isembedded in.型別 member 成員變數 the na...
Linux核心模組
核心模組 在整個啟動的過程中,是否能成功的驅動我們主句的硬體裝置,是核心完成的工作,而核心一般都是壓縮文件,在使用之前核心之前必須要將核心減壓到的記憶體中。為了應對日新月異的硬體,目前核心都具有可讀取模組化驅動程式的功能,也就是所謂的 modules模組化 所謂模組化。核心與核心模組放在 核心 bo...
Linux核心模組
1 核心模組註冊登出 塊載入函式有返回值,模組解除安裝函式無返回值。兩者都是無參函式,載入函式用 init修飾,解除安裝函式用 exit修飾。define init attribute section init.text define exit atrribute section exit,text...