linux 核心模組中的巨集

2021-04-13 07:16:09 字數 3071 閱讀 8398

[email protected]

編寫模組時一般都需要包含標頭檔案,而在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...