日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

简单实例讲解linux的module模块编译步骤

發布時間:2025/3/15 linux 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简单实例讲解linux的module模块编译步骤 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡單實例講解linux的module模塊編譯步驟

(2014-10-24 10:19:17)
標簽:

module

linux

分類:Linux/Unix

本文將直接了當的帶你進入linux的模塊編譯。當然在介紹的過程當中,我也會添加一些必要的注釋,以便初學者能夠看懂。之所以要寫這篇文章,主要是因為從書本上學的話,可能要花更長的時間才能學會整個過程,因為看書的話是一個學習過程,而我這篇文章更像是一個培訓。所以實踐性和總結性更強。通過本文你將會學到編譯一個模塊和模塊makefile的基本知識。以及加載(卸載)模塊,查看系統消息的一些知識;

聲明:本文為初學者所寫,如果你已經是一個linux模塊編譯高手,還請指正我文章中的錯誤和不足,謝謝

第一步:準備源代碼

首先我們還是要來編寫一個符合linux格式的模塊文件,這樣我們才能開始我們的模塊編譯。假設我們有一個源文件mymod.c。它的源碼如下:

mymod.c

  • #include???????
  • #include???????????
  • #include???
  • MODULE_AUTHOR("Yu?Qiang");??
  • MODULE_LICENSE("GPL");???
  • static?int?nbr?=?10;??
  • module_param(nbr,?int,?S_IRUGO);??
  • ??
  • static?int?__init?yuer_init(void)??
  • {??
  • ????int?i;??
  • ????for(i=0;?i
  • ????{??
  • ????????printk(KERN_ALERT?"Hello,?How?are?you.?%d\n",?i);??
  • ????}??
  • ????return?0;??
  • }??
  • ??
  • static?void?__exit?yuer_exit(void)??
  • {??
  • ????printk(KERN_ALERT"I?come?from?yuer's?module,?I?have?been?unlad.\n");??
  • }??
  • module_init(yuer_init);??
  • module_exit(yuer_exit);??



  • 我們的源文件就準備的差不多了,這就是一個linux下的模塊的基本結構。第9行是導出我們的符號變量nbr。這樣在你加載這個模塊的時候可以動態修改這個變量的值。稍后將演示。yuer_init()函數將在模塊加載的時候運行,通過輸出的結果可以看到我們的模塊是否加載成功。


    第二步:編寫Makefile文件
    ????
    首先還是來看看我們Makefile的源文件,然后我們再來解釋;

    Makefile
    obj-m :=modules.o??????????????????? #要生成的模塊名 ?????
    modules-objs:=? mymod .o???????? #生成這個模塊名所需要的目標文件

    KDIR := /lib/modules/`uname -r`/build
    PWD := $(shell pwd)

    default:
    make -C $(KDIR) M=$(PWD) modules

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


    現在我來說明一下這個Makefile。請記住是大寫的Makefile而不是小寫的makefile;
    obj-m :這個變量是指定你要聲稱哪些模塊模塊的格式為 obj-m :=<模塊名>.o
    modules-objs:這個變量是說明聲稱模塊modules需要的目標文件 格式要求??<模塊名>-objs := <目標文件>
    ??????切記:模塊的名字不能取與目標文件相同的名字。如在這里模塊名不能取成 mymod;
    KDIR??:這是我們正在運行的操作系統內核編譯目錄。也就是編譯模塊需要的環境
    M=????:指定我們源文件的位置
    PWD??:這是當前工作路徑$(shell??)是make的一個內置函數。用來執行shell命令。


    第三步:編譯模塊

    現在我們已經準備好了我們所需要的源文件和相應的Makefile。我們現在就可以編譯了。在終端進入源文件目錄輸入make
    運行結果:
  • make[1]:?Entering?directory?`/usr/src/linux-headers-2.6.24-24-generic'??
  • CC?[M]?/home/yuqiang/桌面/mymodule/mymodules.o??
  • LD?[M]?/home/yuqiang/桌面/mymodule/modules.o??
  • Building?modules,?stage?2.??
  • MODPOST?1?modules??
  • CC??????/home/yuqiang/桌面/mymodule/modules.mod.o??
  • LD?[M]?/home/yuqiang/桌面/mymodule/modules.ko??
  • make[1]:?Leaving?directory?`/usr/src/linux-headers-2.6.24-24-generic'??




  • 第四步:加載/卸載我們的模塊

    從上面的編譯中我可以看到。已經有一個modules.ko生成了。這就是我們的模塊了。現在我們就可以來加載了。
    首先在終端輸入: sudoinsmod modules.ko
    現在我們來看看我們的模塊加載成功沒有呢?
    在終端輸入: dmesg| tail-12??? 這是查看內核輸出信息的意思。tail-12 顯示最后12條;
    顯示結果如下:
  • [17945.024417]?sd?9:0:0:0:?Attached?scsi?generic?sg2?type?0??
  • [18046.790019]?usb?5-8:?USB?disconnect,?address?9??
  • [19934.224812]?Hello,?How?are?you.?0??
  • [19934.224817]?Hello,?How?are?you.?1??
  • [19934.224818]?Hello,?How?are?you.?2??
  • [19934.224820]?Hello,?How?are?you.?3??
  • [19934.224821]?Hello,?How?are?you.?4??
  • [19934.224822]?Hello,?How?are?you.?5??
  • [19934.224824]?Hello,?How?are?you.?6??
  • [19934.224825]?Hello,?How?are?you.?7??
  • [19934.224826]?Hello,?How?are?you.?8??
  • [19934.224828]?Hello,?How?are?you.?9??



  • 看到了吧。我們的模塊的初始化函數yuer_init();已經成功運行了。說明我們的模塊已經加載成功;
    現在我們再來卸載模塊試試看。
    在終端輸入: sudormmod modules
    在終端輸入: dmesg| tail -3
  • [19934.224826]?Hello,?How?are?you.?8??
  • [19934.224828]?Hello,?How?are?you.?9??
  • [20412.046932]?I?come?from?yuer's?module,?I?have?been?unlad.??



  • 可以從打印的信息中看到,我們的模塊的退出函數已經被執行了。說明我們的模塊已經被成功的卸載了。到目前位置我們就已經算是對模塊的編譯到編譯運行算是有了一個整體上的認識了。對于以后深入的學習還是應該有點幫助的。下面我們將在看看于模塊相關的一些簡單的操作。


    第五步:加載模塊時傳遞參數
    在終端輸入: sudoinsmod module_name.ko nbr=4
    在終端輸入: dmesg| tail -6
    顯示結果如下:
  • [20800.655694]?Hello,?How?are?you.?9??
  • [21318.675593]?I?come?from?onefile?module,?I?have?been?unlad.??
  • [21334.425373]?Hello,?How?are?you.?0??
  • [21334.425378]?Hello,?How?are?you.?1??
  • [21334.425380]?Hello,?How?are?you.?2??
  • [21334.425381]?Hello,?How?are?you.?3??



  • 這樣我們就可以看到在模塊加載的時候動態設置了我們的一個變量。初始化函數中的循環只執行了4次。
    可能你會問我怎么知道一個模塊可以設置那些變量呢。當然,你可以先不設變量加載一次。然后可以在終端輸入ls/sys/module//parameters/來查看。在這里我們是這樣輸入的
    在終端輸入: ls/sys/moedle/modules/parameters/
    顯示結果:
    nbr

    如果我們的模塊加載成功了。最后我們還可以通過modinfo來查看我們的模塊信息。如下
    在終端輸入: sudomodinfo modules.ko
    ???顯示結果:
  • filename:???????modules.ko??
  • license:????????GPL??
  • author:?????????Yu?Qiang??
  • srcversion:?????20E9C3C4E02D130E6E92533??
  • depends:??????????
  • vermagic:???????2.6.24-24-generic?SMP?mod_unload?586???
  • parm:???????????nbr:int??



  • 本文總結:
    ???本文的相關知識都好像有一點淺嘗轍止的感覺。因為本篇文章主要是通過一條線式方式來講解了模塊編寫的相關過程,其實在這個過程中還有很多可以發散的地方。例如:
    在寫到MODULE_AUTHOR("Yu Qiang")的時候,你應該想到還有
    ????MODULE_DESCRIPTION(模塊用途的簡單描述);
    ????MODULE_VERSION(模塊的版本字符串);
    ????MODULE_ALIAS(模塊的別名);
    ????...

    在寫到module_param(nbr, int, S_IRUGO);的時候,你應該想到還有
    ????EXPORT_SYMBOL(name); 可以導出模塊的函數,這也是模塊編寫的最終目的
    ...

    在用到insmod 和 modinfo的時候。你應該想到還有
    ????depmod????分析可加載模塊的依賴性,并生成modules.dep文件和映射文件
    ????modprobe???Linux內核添加刪除模塊
    ...

    總結

    以上是生活随笔為你收集整理的简单实例讲解linux的module模块编译步骤的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。