日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响(一)

發(fā)布時間:2025/7/14 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响(一) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2.4 2.6Linux 內(nèi)核可裝載模

? 塊機制的改變對設備驅(qū)動的影響

?? <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

(此文章非常精彩,強烈推薦)

?

2.4 2.6Linux 內(nèi)核在可裝載模塊機制、設備模型、一些核心 API 等方面發(fā)生較大改變,設備驅(qū)動開發(fā)人員面臨著將驅(qū)動從 2.4 移植到 2.6 內(nèi)核,或是使驅(qū)動同時支持2.4 2.6 內(nèi)核的任務。站在設備驅(qū)動開發(fā)人員的角度,驅(qū)動由一個或幾個外部可加載內(nèi)核模塊組成,本文針對 2.6 內(nèi)核里模塊機制的改變對編寫設備驅(qū)動程序的影響,從內(nèi)核模塊的編譯、裝載時的版本檢查、初始化與退出、模塊使用計數(shù)、輸出內(nèi)核符號、命令行輸入?yún)?shù)、許可證聲明等方面比較了 2.4 2.6 內(nèi)核的區(qū)別;并總結(jié)了使設備驅(qū)動同時支持 2.4 2.6 內(nèi)核的一系列模板。

1. 獲取內(nèi)核版本

當設備驅(qū)動需要同時支持不同版本內(nèi)核時,在編譯階段,內(nèi)核模塊需要知道當前使用的內(nèi)核源碼的版本,從而使用相應的內(nèi)核 API2.4 2.6 內(nèi)核下,源碼頭文件 linux/version.h 定義有:

LINUX_VERSION_CODE ― 內(nèi)核版本的二進制表示,主、從、修訂版本號各對應一個字節(jié);

KERNEL_VERSION(major, minor, release) - 由主、從、修訂版本號構(gòu)造二進制版本號。

在同時支持2.42.6 內(nèi)核的設備驅(qū)動程序中,經(jīng)常可以看到以下代碼段:


清單1:判斷內(nèi)核版本的代碼段。

#include <linux/version.h>

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)

#define LINUX26

#endif

#ifdef LINUX26

/*code in 2.6 kernel*/

#else

/*code in 2.4 kernel */

#endif

?

?

?

2.內(nèi)核模塊機制的改變

2.1模塊編譯

2.42.6,外部可裝載內(nèi)核模塊的編譯、連接過程以及Makefile的書寫都發(fā)生了改變。

2.4內(nèi)核中,模塊的編譯只需內(nèi)核源碼頭文件;需要在包含linux/modules.h之前定義MODULE;編譯、連接后生成的內(nèi)核模塊后綴為.o

2.6內(nèi)核中,模塊的編譯需要配置過的內(nèi)核源碼;編譯、連接后生成的內(nèi)核模塊后綴為.ko;編譯過程首先會到內(nèi)核源碼目錄下,讀取頂層的Makefile文件,然后再返回模塊源碼所在目錄。


清單22.4 內(nèi)核模塊的Makefile模板

???????

#Makefile2.4

KVER=$(shell uname -r)

KDIR=/lib/modules/$(KVER)/build

OBJS=mymodule.o

CFLAGS=-D__KERNEL__ -I$(KDIR)/include -DMODULE -D__KERNEL_SYSCALLS__ -DEXPORT_SYMTAB

? -O2 -fomit-frame-pointer? -Wall? -DMODVERSIONS -include $(KDIR)/include/linux/modversions.h

all: $(OBJS)

mymodule.o: file1.o file2.o

??????? ld -r -o $@ $^

clean:

??????? rm -f *.o

???????

?

2.4 內(nèi)核下內(nèi)核模塊的Makefile與普通用戶程序的Makefile在結(jié)構(gòu)和語法上都相同但是必須在CFLAGS中定義-D__KERNEL__-DMODULE指定內(nèi)核頭文件目錄-I$(KDIR)/include 有一點需注意,之所以在CFLAGS中定義變量,而不是在模塊源碼文件中定義,一方面這些預定義變量可以被模塊中所有源碼文件可見,另一方面等價于將這些預定義變量定義在源碼文件的起始位置。在模塊編譯中,對于這些全局的預定義變量,一般在CFLAGS中定義。


清單32.6 內(nèi)核模塊的Makefile模板

# Makefile2.6

ifneq ($(KERNELRELEASE),)

#kbuild syntax. dependency relationshsip of files and target modules are listed here.

mymodule-objs := file1.o file2.o

obj-m := mymodule.o

else

PWD? := $(shell pwd)

KVER ?= $(shell uname -r)

KDIR := /lib/modules/$(KVER)/build

all:

??????? $(MAKE) -C $(KDIR) M=$(PWD)

clean:

rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions

endif

?

KERNELRELEASE是在內(nèi)核源碼的頂層Makefile中定義的一個變量,在第一次讀取執(zhí)行此Makefile時,KERNELRELEASE沒有被定義, 所以make將讀取執(zhí)行else之后的內(nèi)容。如果make的目標是clean,直接執(zhí)行clean操作,然后結(jié)束。當make的目標為all時,-C $(KDIR) 指明跳轉(zhuǎn)到內(nèi)核源碼目錄下讀取那里的MakefileM=$(PWD) 表明然后返回到當前目錄繼續(xù)讀入、執(zhí)行當前的Makefile。當從內(nèi)核源碼目錄返回時,KERNELRELEASE已被被定義,kbuild也被啟動去解析kbuild語法的語句,make將繼續(xù)讀取else之前的內(nèi)容。else之前的內(nèi)容為kbuild語法的語句, 指明模塊源碼中各文件的依賴關系,以及要生成的目標模塊名。mymodule-objs := file1.o file2.o表示mymoudule.o file1.ofile2.o 連接生成。obj-m := mymodule.o表示編譯連接后將生成mymodule.o模塊。

補充一點,"$(MAKE) -C $(KDIR) M=$(PWD)""$(MAKE) -C $(KDIR) SUBDIRS =$(PWD)"的作用是等效的,后者是較老的使用方法。推薦使用M而不是SUBDIRS,前者更明確。

通過以上比較可以看到,從Makefile編寫來看,在2.6內(nèi)核下,內(nèi)核模塊編譯不必定義復雜的CFLAGS,而且模塊中各文件依賴關系的表示簡潔清晰。


清單4: 可同時在2.4 2.6 內(nèi)核下工作的Makefile

Makefile for 2.4 & 2.6

VERS26=$(findstring 2.6,$(shell uname -r))

MAKEDIR?=$(shell pwd)

ifeq ($(VERS26),2.6)

include $(MAKEDIR)/Makefile2.6

else

include $(MAKEDIR)/Makefile2.4

endif

?

?

2.2模塊裝載時的版本檢查

Linux內(nèi)核一直在更新、完善,在a版本內(nèi)核源碼下編譯的模塊在b版本內(nèi)核下通常不能運行,所以必須有一種機制,限制在a版本內(nèi)核下編譯生成的模塊在b版本內(nèi)核下被加載。

2.42.6內(nèi)核在可裝載內(nèi)核模塊的版本檢查機制方面發(fā)生了根本性的改變,不過這些改變對設備驅(qū)動開發(fā)人員而言基本是透明的。為了使模塊裝載時的版本檢查機制生效,2.4 內(nèi)核下,只需在CFLAGS中定義

?

-DMODVERSIONS -include $(KDIR)/include/linux/modversions.h

?

2.6內(nèi)核下,開發(fā)人員無須采用任何操作。

不過,在此仍有必要闡明2.42.6內(nèi)核對可加載模塊的版本檢查機制。

2.4內(nèi)核下, 執(zhí)行`cat /proc/ksyms`可看到內(nèi)核符號在名字后還跟隨著一串校驗字符串,此校驗字符串與內(nèi)核版本有關。在內(nèi)核源碼頭文件linux/modules 目錄下存在許多*.ver文件,這些文件起著為內(nèi)核符號添加校驗后綴的作用,如ksyms.ver 文件里有一行 #define printk _set_ver(printk)linux/modversions.h 文件會包含全部的 ver文件 。所以當模塊包含linux/modversions.h文件后,編譯時,模塊里使用的內(nèi)核符號實質(zhì)是帶有校驗后綴的內(nèi)核符號。在加載模塊時,如果模塊中所使用內(nèi)核符號的校驗字符串與當前運行內(nèi)核所導出的相應的內(nèi)核符號的校驗字符串不一致,即當前內(nèi)核空間并不存在模塊所使用的內(nèi)核符號,就會出現(xiàn)"Invalid module format "的錯誤。

為內(nèi)核符號添加校驗字符串來驗證模塊的版本與內(nèi)核的版本是否匹配是繁雜和浪費內(nèi)核空間的;而且隨著SMP(對稱多處理器)、PREEMPT(可搶占內(nèi)核)等機制在2.6內(nèi)核的引入和完善,模塊運行時對內(nèi)核的依賴不僅取決于內(nèi)核版本,還取決于內(nèi)核的配置,此時內(nèi)核符號的校驗碼是否一致不能成為判斷模塊可否被加載的充分條件。2.6 內(nèi)核下,在linux/vermagic.h中定義有VERMAGIC_STRINGVERMAGIC_STRING不僅包含內(nèi)核版本號,還包含有內(nèi)核使用的gcc版本,SMPPREEMPT等配置信息。模塊在編譯時,我們可以看到屏幕上會顯示"MODPOST"。在此階段, VERMAGIC_STRING會添加到模塊的modinfo段。 在內(nèi)核源碼目錄下scripts\mod\modpost.c文件中可以看到模塊后續(xù)處理部分的代碼。模塊編譯生成后,通過`modinfo mymodule.ko`命令可以查看此模塊的vermagic等信息。2.6 內(nèi)核下的模塊裝載器里保存有內(nèi)核的版本信息,在裝載模塊時,裝載器會比較所保存的內(nèi)核vermagic與此模塊的modinfo段里保存的vermagic信息是否一致,兩者一致時,模塊才能被裝載。譬如Fedora core 4 core 2 使用的都是2.6 版本內(nèi)核, 在Fedore Core 2下去加載Fedora Core4下編譯生成的hello.ko,會出現(xiàn)"invalid module format" 錯誤。

?

insmod hello.ko

Invalid module format

hello: version magic '2.6.11-1.1369_FC4 686 REGPARM 4KSTACKS gcc-4.0'

should be '2.6.5-1.358 686 REGPARM 4KSTACKS gcc-3.3'

?

2.3模塊的初始化與退出

2.6內(nèi)核中,內(nèi)核模塊必須調(diào)用宏module_init module_exit() 去注冊初始化與退出函數(shù)。在2.4 內(nèi)核中,如果初始化函數(shù)命名為init_module()、退出函數(shù)命名為cleanup_module(),可以不必使用module_init module_exit 宏。推薦使用module_init module_exit宏,使代碼在2.42.6內(nèi)核中都能工作。


清單5:適用于2.42.6內(nèi)核的模塊的初始化與退出模板

#include <linux/module.h>? /* Needed by all modules */

#include <linux/init.h>??? /* Needed for init&exit macros */

static int mod_init_func(void)

{

/*code here*/

return 0;

}

static void mod_exit_func(void)

{

/*code here*/

}

module_init(mod_init_func);

module_exit(mod_exit_func);

?

需要注意的是初始化與退出函數(shù)必須在宏module_initmodule_exit使用前定義,否則會出現(xiàn)編譯錯誤。

?

?

轉(zhuǎn)載于:https://blog.51cto.com/zyg0227/270373

總結(jié)

以上是生活随笔為你收集整理的从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。