首先介紹一下__init這個標誌在驅動原始檔中的作用吧。
核心中帶「__」的函式:核心api函式具有這種名稱的,通常都是一些介面的底層函式,應該謹慎使用。實質上,這裡的雙下劃線就是要告訴程式設計師:謹慎呼叫,否則後果自負。以__init為例,__init表明該函式僅在初始化期間使用。在模組被裝載之後,模組裝載器就會將初始化函式扔掉,這樣可以將函式占用的記憶體釋放出來,已做它用。注意,不要在結束初始化之後仍要使用的函式(或者資料結構)上使用__init、__initdata標記。這裡摘抄網上的一段總結,如下。
__init, __initdata等屬性標誌,是要把這種屬性的**放入目標檔案的.init.text節,資料放入.init.data節──這一過程是通過編譯核心時為相關目標平台提供了***.lds鏈結指令碼來指導ld完成的。
對編譯成module的**和資料來說,當模組載入時,__init屬性的函式就被執行;
對靜態編入核心的**和資料來說,當核心引導時,do_basic_setup()函式呼叫do_initcalls()函式,後者負責所有.init節函式的執行。
在初始化完成後,用這些關鍵字標識的函式或資料所佔的記憶體會被釋放掉。
1) 所有標識為__init的函式在鏈結的時候都放在.init.text這個區段內,在這個區段中,函式的擺放順序是和鏈結的順序有關的,是不確定的。
2) 所有的__init函式在區段.initcall.init中還儲存了乙份函式指標,在初始化時核心會通過這些函式指標呼叫這些__init函式指標,並在整個初始化完成後,釋放整個init區段(包括.init.text,.initcall.init等),注意,這些函式在核心初始化過程中的呼叫順序只和這裡的函式指標的順序有關,和1)中所述的這些函式本身在.init.text區段中的順序無關。
接下來說明一下如果有多個原始檔來編譯鏈結組成最終的驅動.ko檔案,那麼他們的makefile該如何書寫。
核心模組的編譯與應用程式的編譯有些區別,此hello world模組的編譯命令為:
make -c /***/***/kernel_src/ m=$(pwd) modules
其中/***/***/kernel_src/ 為已經配置編譯過的核心原始碼路徑,ubuntu下一般在/lib/modules/$(shell uname -r)/build目錄下。
在編寫應用程式時,我們一般都是由多個原始檔組成的,這個時候編譯肯定就不能繼續使用命令列編譯了,就要使用到makefile。同樣,驅動模組的編譯也需要使用的makefile,下面就是乙個在編譯含有多個原始碼檔案的驅動模組時可以參考的makefile檔案。
在編寫應用程式時,我們一般都是由多個原始檔組成的,這個時候編譯肯定就不能繼續使用命令列編譯了,就要使用到makefile。同樣,驅動模組的編譯也需要使用的makefile,下面就是乙個在編譯含有多個原始碼檔案的驅動模組時可以參考的makefile檔案。
ifndef cross_compile
export cross_compile ?=arm-none-linux-gnueabi-
endif
arch ?= arm
src_dir := /home/***/***
obj_dir := $(src_dir)/obj
pwd := $(shell pwd)
linux_src ?= /home/***/kernel
cfg_inc = -i$(src_dir) \
-i$(dir_a) \
-i$(dir_b)
cfg_flags += -o2
extra_cflags += $(c_flags) $(cfg_inc) $(cfg_inc)
obj-m := mymodule.o
mymodule-objs := a.o
mymodule-objs += b.o
mymodule-objs += c.o
modules:
@make arch=$(arch) -c $(linux_src) m=$(pwd) modules
clean:
@echo "cleaning..."
rm -f mymodule.ko mymodule.o mymodule.mod.* modules.order module.symvers
rm -f $(mymodule-objs)
Linux字元裝置驅動初探
一 裝置驅動之資料結構 1 dev t 裝置編號,包含主裝置號 次裝置號。dev t是乙個32位的數,12位表示主裝置號,20為表示次裝置號 1 主裝置號 major dev t dev 2 次裝置號 minor dev t dev 3 裝置編號 mkdev int major,int minor ...
Linux裝置驅動初探 準備Linux原始碼樹
剛看 o reilly 寫的 linux 裝置驅動程式 時。作者一再強調在編寫驅動程式時必須 建立核心樹。所謂核心樹,我的理解和網上資料說的一致就是核心原始碼的一種邏輯形式。那怎麼建立呢?為此上網 翻雲覆雨 起來而結果卻是 慘敗而歸 為 此託了一天又4個小時 當然包括吃飯睡覺的時間 連個簡單的 he...
Linux裝置驅動程式初探示例
本示例為在linux裝置驅動程式中文版第三版中摘錄出來的示例程式 程式原始碼 hello.c include include include 告知核心該模組帶有乙個自由許可證 module license dual bsd gpl 模組載入時被呼叫 static int init hello ini...