內核與驅動文件的version magic匹配問題


https://blog.csdn.net/yubing_615/article/details/52183185

1.問題:本地編譯的一整套底層代碼down到設備跑都正常,但是由這套代碼上傳SVN服務器而后checkout出來的代碼編譯的文件,則出現驅動文件加載不上的情況(驅動以模塊方式加載),打印如下
emotor_drv: version magic '3.4.39-lhx SMP preempt mod_unload ARMv7 p2v8 ' should be '3.4.39-9tripod SMP preempt mod_unload ARMv7 p2v8 '

2.分析:初步由打印log信息看,是由version magic不匹配造成,找到信息打印點,kernel/module.c

點擊(此處)折疊或打開

  1. printk(KERN_ERR "%s: version magic '%s' should be '%s'\n",
  2.          mod->name, modmagic, vermagic);

然后

點擊(此處)折疊或打開

  1. static const char vermagic[] = VERMAGIC_STRING;

可知打印語句實際由宏VERMAGIC_STRING定義,接着看include/linux/vermagic.h

點擊(此處)折疊或打開

  1. #define VERMAGIC_STRING                         \
  2.     UTS_RELEASE " "                            \
  3.     MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT             \
  4.     MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS    \
  5.     MODULE_ARCH_VERMAGIC

打印信息的不同點“'3.3.0”和“3.3.0-svn87”是由宏UTS_RELEASE生成,那么重點關注UTS_RELEASE
由名字推測是編譯內核時版本號給打上了svn相關標記,但是在內核源碼中沒看到任何地方定義UTS_RELEASE,再到Makefile找,搜到這句

  1. (echo \#define UTS_RELEASE \"$(KERNELRELEASE)\";)

再搜KERNELRELEASE

  1. # Read KERNELRELEASE from include/config/kernel.release (if it exists)
  2.  382 KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
  3.  383 KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)

可見KERNELRELEASE由include/config/kernel.release文件讀取獲得,但是內核源碼中並無此文件(為查找差異之前將內核make distclean掉了),

再重新編譯

一次,果然生成了include/config/kernel.release文件,查看內容

  1. cat include/config/kernel.release
  2. 3.3.0-svn87

找到了加載驅動時打印log里的“3.3.0-svn87

再回到Makefile,搜kernel.release

  1. # Store (new) KERNELRELASE string in include/config/kernel.release
  2.  951 include/config/kernel.release: include/config/auto.conf FORCE
  3.  952 $(Q)rm -f $@
  4.  953 $(Q)echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" > $@

kernel.release就是在這里生成的,前面版面號忽略,“-svn87”實際上是執行setlocalversion得到svn版本號加上去的;

查看得知setlocalversion是一個腳本文件,支持自動獲取svn,git等源碼管理工具的版本號;

 

 

3.沒有驅動源碼的解決方案:

 只需要使version magic一致,驅動就可以順利加載;由於廠商提供的部分驅動文件沒提供源碼,並且本地內核也會不斷升級(svn版本號會變),所

以最簡單的方法是將

附加的-svnXX去掉,這樣現存的驅動和后續編譯的驅動和內核就都可以保持一致了:

修改如下,

vi   kernel/Makefile 更該為如下代碼。

  1. include/config/kernel.release: include/config/auto.conf FORCE
  2.  952 $(Q)rm -f $@
  3.  953 #     $(Q)echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" > $@
  4.  954       $(Q)echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree))" > $@

重新編譯后,驅動可以正常加載工作了。

PS:當然,version magic是一個很好的功能,如果所有驅動都有源碼,對於發布產品的版本,加上svn版本號標記可以有效保證內核驅動版本一致性。


 

4.不改變uImage的解決方案:

vi    kernel/Makefile 更該為如下代碼。

950 include/config/kernel.release: include/config/auto.conf FORCE
951         $(Q)rm -f $@
952         $(Q)echo "3.4.39-9tripod" > $@
953         #$(Q)echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/set     localversion $(srctree))" > $@

之后重新編譯編譯內核,再重新編譯驅動就可以了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM