核心模組學習–編譯自己的第一個核心模組hello_module

來源:互聯網
上載者:User


1,下載源碼
xin@xin-desktop:~$  sudo apt-get source linux-image-2.6.32-38-generic
最終安裝在目錄:/usr/src/linux-2.6.32/
2,編寫源碼hello_module.c和Makefile
(1)建立一個目錄mytest
xin@xin-desktop:~/mytest$ vi hello_module.c

    #include <linux/init.h>         /* printk() */    #include <linux/module.h>       /* __init __exit */    static int  __init  hello_init(void)      /*模組載入函數,通過insmod命令載入模組時,被自動執行*/    {      printk(KERN_INFO " Hello World enter\n");      return 0;    }    static void  __exit  hello_exit(void)    /*模組卸載函數,當通過rmmod命令卸載時,會被自動執行*/    {      printk(KERN_INFO " Hello World exit\n ");    }    module_init(hello_init);    module_exit(hello_exit);    MODULE_AUTHOR("xin");           /*模組作者,可選*/    MODULE_LICENSE("Dual BSD/GPL");     /*模組許可證明,描述核心模組的許可許可權,必須*/    MODULE_DESCRIPTION("A simple Hello World Module"); /*模組說明,可選*/


(2)寫一個Makefile檔案:
內容如下:

#目標檔案obj-m :=hello_module.o#當模組有多個檔案組成時,添加本句#module-objs := file1.o file.o  #核心路徑,根據實際情況換成自己的核心路徑,嵌入式的換成嵌入式,PC機的指定PC機路>徑      KDIR :=/usr/src/linux-2.6.32/#模組源檔案路徑             PWD := $(shell pwd)all:              $(MAKE)  -C  $(KDIR)  SUBDIRS=$(PWD)  modules          @rm -rf *.mod.*          @rm -rf .*.cmd          @rm -rf *.o          @rm -rf Module.*  clean:          rm -rf *.ko


 
3,編譯
xin@xin-desktop:~/mytest$  make
make: Entering directory `/usr/src/linux-2.6.32'

  ERROR: Kernel configuration is invalid.
         include/linux/autoconf.h or include/config/auto.conf are missing.
         Run 'make oldconfig && make prepare' on kernel src to fix it.

  WARNING: Symbol version dump /usr/src/linux-2.6.32/Module.symvers
           is missing; modules will have no dependencies and modversions.

  ........................................
  ........................................

解決方案:
xin@xin-desktop:/usr/src/linux-2.6.32$ sudo make oldconfig
xin@xin-desktop:/usr/src/linux-2.6.32$ sudo make prepare

再次編譯:
xin@xin-desktop:~/mytest$ make
還是有錯:
make: Entering directory `/usr/src/linux-2.6.32'

  WARNING: Symbol version dump /usr/src/linux-2.6.32/Module.symvers
           is missing; modules will have no dependencies and modversions.

  CC [M]  /home/xin/mytest/hello_module.o
  Building modules, stage 2.
  MODPOST 1 modules
/bin/sh: scripts/mod/modpost: not found
make[1]: *** [__modpost] 錯誤 127
make: *** [modules] 錯誤 2
make: Leaving directory `/usr/src/linux-2.6.32'

看到提示說沒有scripts/mod/modpost,那我們就編譯它
xin@xin-desktop:/usr/src/linux-2.6.32$ make scripts
  HOSTCC  scripts/genksyms/genksyms.o
  SHIPPED scripts/genksyms/lex.c
  SHIPPED scripts/genksyms/parse.h
  SHIPPED scripts/genksyms/keywords.c
  HOSTCC  scripts/genksyms/lex.o
  SHIPPED scripts/genksyms/parse.c
 HOSTCC  scripts/genksyms/parse.o
  HOSTLD  scripts/genksyms/genksyms
  CC      scripts/mod/empty.o
  HOSTCC  scripts/mod/mk_elfconfig
  MKELF   scripts/mod/elfconfig.h
  HOSTCC  scripts/mod/file2alias.o
  HOSTCC  scripts/mod/modpost.o
  HOSTCC  scripts/mod/sumversion.o
  HOSTLD  scripts/mod/modpost
  HOSTCC  scripts/kallsyms
  HOSTCC  scripts/conmakehash

OK,好了

再來解決這一個warning(前面沒有關注,後面發現這個還是致命的):
 WARNING: Symbol version dump /usr/src/linux-2.6.32/Module.symvers
           is missing; modules will have no dependencies and modversions.

原因:通常頭核心包中是沒有Module.symvers這個檔案的,要想擷取這個檔案只能到下載相同版本核心的標頭檔,是下載不是
apt-get install  !!!,只有下載的標頭檔中才有這個Module.symvers。把Module.symvers 複製到核心包中。
然後重新編譯驅動:xin@xin-desktop:~/mytest$ make
將解決這個warning,同時也解決了版本不正確的問題。
(我不知道有多少人會碰上這樣的問題,反正google中我發現沒有人能說明白這個問題)

4,載入模組
xin@xin-desktop:~/mytest$ ls
hello_module.c   modules.order   hello_module.ko  Makefile  
xin@xin-desktop:~/mytest$ sudo insmod hello_module.ko
xin@xin-desktop:~/mytest$ lsmod | grep hello_module
hello_module             593  0

ps:
不解決上面的warning,是可以編譯成功的。但是在執行載入後
xin@xin-desktop:~/mytest$ sudo insmod hello_module.ko
報錯:insmod: error inserting 'hellomod.ko': -1 Invalid module format
查了很多資料,普遍的觀點是:
核心無法載入模組的原因是因為記載版本號碼的字串(正規說法:版本印戳)和當前正在啟動並執行核心模組的不一樣,叫vermagic
此時,可用sudo tail /var/log/messages
你在最後一行應該看到類似下面的提示:
Dec 19 13:42:29 localhost kernel: hellomod: version magic '2.6.24.2 SMP mod_unload 686 4KSTACKS ' should be '2.6.27.7-134.fc10.i686 SMP mod_unload 686 4KSTACKS '
而我的只顯示:
Mar 29 16:57:34 xin-desktop kernel: [ 6964.464931] hello_module: no symbol version for module_layout
但是通過modinfo和 uname -r的比較確實不一樣

我按照提供的辦法,修改來源目錄下的Makefie
把Makefile第1-4行的值改為當前核心一樣的值
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 32
EXTRAVERSION = .54+drm33.21
NAME = Man-Eating Seals of Antiquity

確定你當前核心的值,通過
vi  /lib/modules/`uname -r`/build/Makefile

但是,我這樣改過之後,還是又上面載入不上的問題,而且版本號碼跟寫進Makefile的不是一樣的,編譯完成的是這樣的:
2.6.32.57+drm33.23 SMP mod_unload modversions 586。
即便我把/usr/src/linux-2.6.32核心源碼中的Makefile改了,也是這樣的,我一直沒有搞清楚,到底核心版本號碼是在哪裡設定的。
最後,消除了這個warning後,雖然核心版本號碼仍不一樣,但是可以載入了。
當前已經載入的核心模組video的資訊:
xin@xin-desktop:~/mytest$ modinfo video
filename:       /lib/modules/2.6.32-38-generic/kernel/drivers/acpi/video.ko
license:        GPL
description:    ACPI Video Driver
author:         Bruno Ducrot
srcversion:     A52E70043443277D9757C8E
alias:          acpi*:LNXVIDEO:*
depends:        output
vermagic:       2.6.32-38-generic SMP mod_unload modversions 586
parm:           brightness_switch_enabled:bool

hello_module的資訊:
xin@xin-desktop:~/mytest$ modinfo hello_module.ko
filename:       hello_module.ko
alias:          a simplest module
description:    A simple Hello World Module
license:        Dual BSD/GPL
author:         xin
srcversion:     B757E1EEAD29F16BF0B6737
depends:        
vermagic:       2.6.32.57+drm33.23 SMP mod_unload modversions 586

注意到 兩者的vermagic是不一樣的,但是可以載入hello_module.ko模組

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.