移植驅動完畢后加載時的version magic報錯原因以及解決辦法

History:2012-02-17
Author:yingru

移植rt3070的AP驅動到裝有fedora14的PC機上時,模塊編譯完畢后,加載時提示invalid module format。
PC機環境介紹:
內核版本:2.6.35.6-45.fc14.i686
命令行輸入dmesg查看最后的日志,發現如下錯誤記錄:
rtutil3070ap:version magic '2.6.35.14-96.fc14.i686 SMP mod_unload 686 ' should be '2.6.35.6-45.fc14.i686 SMP mod_unload 686'
其余幾個模塊也是同樣錯誤

version magic真的是個很惡心的東西。。
既然提示出錯了就去找原因。
查證AP驅動的makefile里內核目錄變量指向的是當前PC機所用內核目錄。/lib/modules/`uname -r`/build
這一步沒有錯。那么說明驅動的makefile是正確的
切換到/lib/modules/`uname -r`/目錄下,查看build(build在此處是一個符號鏈接), ls -al 發現build指向的目錄是/usr/src/kernels/2.6.35.14-96.fc14.i686,問題在這里,雖然我用的目錄是/lib/modules/`uname -r`/build 這個目錄貌似與我當前內核版本(uname -r 即2.6.35.6-45.fc14.i686)一致,但是build這個符號鏈接指向的內核源碼卻是2.6.35.14-96.fc14.i686的,這樣造成了編譯出來的模塊所帶的version magic是2.6.35.14-96.fc14.i686這一版本,加載時與uname -r不符。

那么要解決這一問題,就需要“篡改”一下內核源碼里的version magic 。
驅動模塊的version magic信息是怎么生成的:
2.6 內核下,在linux/vermagic.h中定義有VERMAGIC_STRING,VERMAGIC_STRING不僅包含內核版本號,還包含有內核 使用的gcc版本,SMP與PREEMPT等配置信息。模塊在編譯時,我們可以看到屏幕上會顯示"MODPOST"。在此階段, VERMAGIC_STRING會添加到模塊的modinfo段。在內核源碼目錄下scripts\mod\modpost.c文件中可以看到模塊后續處 理部分的代碼。模塊編譯生成后,通過`modinfo mymodule.ko`命令可以查看此模塊的vermagic等信息。2.6 內核下的模塊裝載器里保存有內核的版本信息,在裝載模塊時,裝載器會比較所保存的內核vermagic與此模塊的modinfo段里保存的 vermagic信息是否一致,兩者一致時,模塊才能被裝載。譬如Fedora core 4 與core 2 使用的都是2.6 版本內核,在Fedore Core 2下去加載Fedora Core4下編譯生成的hello.ko,會出現"invalid module format" 錯誤。
http://www.ibm.com/developerworks/cn/linux/l-module26/
既然是這個道理,那么只需要把/usr/src/kernels/2.6.35.14-96.fc14.i686/目錄下源碼中的include/linux/vermagic.h中的VERMAGIC_STRING修改成與當前PC內核uname -r一致即可。
修改如下:
#define VERMAGIC_STRING ????????????????\
"2.6.35.6-45.fc14.i686"?"" ?????\
MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT??\
MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS \
MODULE_ARCH_VERMAGIC
(描紅為修改處)
具體的格式可以在modinfo yourmodule.ko查看之后 再確定修改哪里 修改完后重新make即可 加載后沒有version magic報錯提示。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/385022.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/385022.shtml
英文地址,請注明出處:http://en.pswp.cn/news/385022.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

/proc 虛擬文件系統(實例)

Linux下有一個神奇的目錄/proc,經常會運行 cat /proc/cpuinfo 命令查看cpu信息,/proc下的確有cpuinfo文件,但是這個文件不是物理存在的,是軟件虛擬出來的,與普通文件不同,該文件是動態的。通過/proc可以實現…

內核模塊中對文件的讀寫

平時網絡部分的東西碰的多些,這塊一開始還真不知道怎么寫,因為肯定和在用戶空間下是不同的。google過后,得到以下答案。一般可以用兩種方法:第一種是用系統調用。第二種方法是filp->open()等函數。下面分別來說下這兩種方法。1…

Makefile文件試錯

1成功&#xff1a; src $(wildcard ./*cpp) obj $(patsubst %.cpp,%.o ,$(src))target test$(target) : $(obj)g $(obj) -o $(target) -I/usr/include/mysql -L/usr/lib/mysql/ -lmysqlclient %.o: %.cppg -c $< -o $ -I/usr/include/mysql -L/usr/lib/mysql/ -lmysql…

內核定時器timer_list使用

Linux內核中提供了timer使用的API&#xff0c;做一個簡單的記要。 1. 包含的頭文件&#xff1a;linux/timer.h 2. 數據類型&#xff1a;struct timer_list; 包含的主要成員&#xff1a; a. data:傳遞到超時處理函數的參數&#xff0c;主要在多個定時器同時使用時&#xff0c;區…

內存四區

1.代碼區&#xff1a; 代碼區Code&#xff0c;程序被操作系統加載到內存的時候&#xff0c;所有的可執行代碼都加載到代碼區&#xff0c;也叫代碼段&#xff0c;這塊內存是不可以在運行期間修改的。 2. 靜態區 所有的全局變量以及程序中的靜態變量都存儲在靜態區。 #include<…

最高效的進(線)程間通信機制--eventfd

我們常用的進程&#xff08;線程&#xff09;間通信機制有管道&#xff0c;信號&#xff0c;消息隊列&#xff0c;信號量&#xff0c;共享內存&#xff0c;socket等等&#xff0c;其中主要作為進程&#xff08;線程&#xff09;間通知/等待的有管道pipe和socketpair。線程還有特…

malloc,calloc,realloc

與堆操作相關的兩個函數 malloc #include<stdio.h> #include<stdlib.h> #include<string.h>int main() {char *p malloc(10); //內存隨機&#xff0c;未做處理int i;for(i 0; i < 10: i){printf(“%d “,p[i]);} free(p);return 0; } 運行結果&…

Linux內核同步機制之completion

內核編程中常見的一種模式是&#xff0c;在當前線程之外初始化某個活動&#xff0c;然后等待該活動的結束。這個活動可能是&#xff0c;創建一個新的內核線程或者新的用戶空間進程、對一個已有進程的某個請求&#xff0c;或者某種類型的硬件動作&#xff0c;等等。在這種情況下…

可變參數函數(一)

一個函數可以接受不定數的參數個數&#xff0c;這就是可變參數函數&#xff0c;比較常見的比如printf(),scanf()&#xff1b; printf(const char* format,…); printf(“%d”,i); printf(“%s”,s); printf(“the number is %d,stirng is :%s”,i,s); 變量參數函數的簡單實現&a…

Linux內核線程kernel thread詳解--Linux進程的管理與調度

內核線程為什么需要內核線程Linux內核可以看作一個服務進程(管理軟硬件資源&#xff0c;響應用戶進程的種種合理以及不合理的請求)。 內核需要多個執行流并行&#xff0c;為了防止可能的阻塞&#xff0c;支持多線程是必要的。 內核線程就是內核的分身&#xff0c;一個分身可以處…

可變參數函數(二)

函數樣例&#xff1a; #include<stdio.h> #include<stdlib.h> #include<stdarg.h>double add(int n,...) {int i 0;double sum 0;va_list argptr;va_start(argptr,n);for(i 0 ; i < n; i){double d va_arg(argptr,double);printf("%d argument …

Linux 內核網絡協議棧 ------sk_buff 結構體 以及 完全解釋 (2.6.16)

在2.6.24之后這個結構體有了較大的變化&#xff0c;此處先說一說2.6.16版本的sk_buff&#xff0c;以及解釋一些問題。一、先直觀的看一下這個結構體~~~~~~~~~~~~~~~~~~~~~~在下面解釋每個字段的意義~~~~~~~~~~~[cpp] view plaincopyprint?struct sk_buff { /* These…

可變參數輸出(三)

Linux C關于輸出函數的定義&#xff1a; int printf(const char *format,…); int vprintf(const char * format,va_list ap); int vfprintf(FILE *stream,cosnt char *format,va_list ap); int vsprintf(char *str,const char *format,va_list ap); int vsnprintf(char *str,s…

最常用的設計模式---適配器模式(C++實現)

適配器模式屬于結構型的設計模式&#xff0c;它是結構型設計模式之首&#xff08;用的最多的結構型設計模式&#xff09;。 適配器設計模式也并不復雜&#xff0c;適配器它是主要作用是將一個類的接口轉換成客戶希望的另外一個接口這樣使得原本由于接口不兼容而不能一起工作的那…

Linux 簡單打印日志(二)

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> //#include<windows.h> #include <unistd.h> // linux下頭文件#define FILE_MAX_SIZE (1024*1024)void get_local_time(char* buffer){time_t rawtime;struct …

程序隨筆——C++實現的一個線程池

1.線程池簡介 我們知道在線程池是一種多線程處理形式&#xff0c;處理過程中我們將相應的任務提交給線程池&#xff0c;線程池會分配對應的工作線程執行任務或存放在任務隊列中&#xff0c;等待執行。 面向對象編程中&#xff0c;創建和銷毀對象是需要消耗一定時間的&#xff0…

線程池原理及創建并C++實現

本文給出了一個通用的線程池框架&#xff0c;該框架將與線程執行相關的任務進行了高層次的抽象&#xff0c;使之與具體的執行任務無關。另外該線程池具有動態伸縮性&#xff0c;它能根據執行任務的輕重自動調整線程池中線程的數量。文章的最后&#xff0c;我們給出一個簡單示例…

Linux 打印簡單日志(一)

簡單日志輸出&#xff1a; #include<stdio.h> #include<string.h> #include<stdlib.h>void write(char* filename,char* szStr){FILE* fp;fp fopen(filename,"at");if(fp ! NULL){fwrite(szStr,256,1,fp); //fclose(fp);fp NULL;} }int main(int…

c++簡單線程池實現

線程池&#xff0c;簡單來說就是有一堆已經創建好的線程&#xff08;最大數目一定&#xff09;&#xff0c;初始時他們都處于空閑狀態&#xff0c;當有新的任務進來&#xff0c;從線程池中取出一個空閑的線程處理任務&#xff0c;然后當任務處理完成之后&#xff0c;該線程被重…

Linux 打印可變參數日志

實現了傳輸進去的字符串所在的文檔&#xff0c;函數和行數顯示功能。 實現了將傳入的可變參數打印到日志功能。 #include<stdio.h> #include<stdarg.h> #include<string.h>const char * g_path "/home/exbot/wangqinghe/log.txt"; #define LOG(fm…