亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 1041 | 回復(fù): 0
打印 上一主題 下一主題

Linux模塊編程[ZT] [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2010-01-17 09:10 |只看該作者 |倒序?yàn)g覽
摘要
Linux內(nèi)核模塊編程的資料有些紛繁復(fù)雜,有的過(guò)于簡(jiǎn)單,有的過(guò)于龐雜,我試圖用筆記的形式想讀者展示怎樣來(lái)進(jìn)程Linux模塊編程,力圖做到簡(jiǎn)明扼要,這篇文章也是作為本人備忘的資料,所以有些地方過(guò)于簡(jiǎn)略是難免的。本來(lái)這篇文章的目的就是讓用戶知其然,至于所以然還是請(qǐng)參考相應(yīng)的資料,其實(shí)最好的資料莫過(guò)于Linux Kernel Source。
適用范圍:

  • Linux Kernel >= 2.6.0 [在2.4.20-8上試了哈,也行]

Linux模塊簡(jiǎn)介
首先這個(gè)module不同于microkernel的module,microkernel的module是一個(gè)個(gè)的daemon進(jìn)程,工作于用戶空間,Linux的module只是一個(gè)內(nèi)核的目標(biāo)代碼,內(nèi)核通過(guò)執(zhí)行運(yùn)行時(shí)的連接,來(lái)把它整合到kernel中去,所以說(shuō)Linux的module機(jī)制并沒(méi)有改變Linux內(nèi)核為monolithic OS本質(zhì),其module也是工作于內(nèi)核模式,享有內(nèi)核的所有特權(quán)。
至于為什么要引入Linux Kernle Module(一下簡(jiǎn)稱LKM),我想至少有一下幾點(diǎn):

  • 模塊化編程的需要,降低開(kāi)發(fā)和維護(hù)成本。
  • 增強(qiáng)系統(tǒng)的靈活性,使得修改一些內(nèi)核功能而不必重新編譯內(nèi)核和重啟系統(tǒng)。
  • 降低內(nèi)核編程的復(fù)雜性,使入門(mén)門(mén)檻降低。

相關(guān)宏及頭文件
LKM需要包含以下頭文件:  
需要定義以下宏:__KERNEL__, MODULE
一個(gè)簡(jiǎn)單的內(nèi)核模塊示例/*file:    hello.c*/
#ifndef __KERNEL__
        #define __KERNEL__
#endif
#ifndef MODULE
        #define MODULE
#endif
#include
#include #include //在2.4.20-8上必須要這個(gè),原文中的內(nèi)核版本沒(méi)有試
static int __init hello_init(void)
{
        printk(KERN_ALERT "Hello, my LKM.\n");
        return 0;
}
static void __exit hello_exit(void)
{
        printk(KERN_ALERT "Bye, my LKM.\n");
}
module_init(hello_init);
module_exit(hello_exit);
很簡(jiǎn)答吧,不是嗎?這個(gè)LKM的功能其實(shí)也很簡(jiǎn)單,就是當(dāng)通過(guò)insmod加載它的時(shí)候,他打印Hello, my LKM.通過(guò)rmmod卸載它的時(shí)候他打印bye, my LKM.一個(gè)最基本的內(nèi)核模塊一般都包含有兩個(gè)函數(shù),一個(gè)是初始化函數(shù)(比如說(shuō)這里的hello_init),一個(gè)是卸載函數(shù)(hello_exit), 當(dāng)然也可以沒(méi)有任何函數(shù),只是提供一些變量。但是初始化函數(shù)和卸載函數(shù)必須成對(duì)出現(xiàn)。并且init函數(shù)當(dāng)操作成功時(shí)返回值大于等于零,當(dāng)操作失敗時(shí),返回非零。宏module_init和module_exit用于注冊(cè)初始化函數(shù)和卸載函數(shù)。
LKM的編譯
一個(gè)示例的Makefile如下所示
obj-m := hello.o
KERNELBUILD := /lib/modules/`uname -r`/build
default:
         make -C $(KERNELBUILD) M=$(shell pwd) modules
clean:
         rm -rf *.o .*.cmd *.ko *.mod.c .tmp_versions
如果這個(gè)目錄下面還有其它模塊,只需要在hello.o后面添加就行了。
obj-m := hello.o mod.o
在模塊所在目錄執(zhí)行make,等成功后就可以得到我們想要的模塊(hello.ko)了。
如果一個(gè)模塊存在許多源文件,比如:hello, 由hello1.c hello2.c共同連接而成,需要在Makefile中加入如下行
hello-objs := hello1.o hello2.o
LKM的加載
Linux為用戶提供了modutils,用來(lái)操縱模塊。這個(gè)工具集主要包括:
insmod 安裝模塊
rmmod 刪除模塊
modprobe 比較高級(jí)的加載和刪除模塊,可以解決模塊之間的依賴性
lsmod 列出已經(jīng)加載的模塊和其信息
modinfo 用于查詢模塊的相關(guān)信息,比如作者,版權(quán)...
試著用命令insmod hello.ko加載模塊,rmmod刪除模塊,看看有什么事情發(fā)生了。你有可能看不見(jiàn)任何輸出,難道是有錯(cuò)誤發(fā)生?No,執(zhí)行命令tail /var/log/message呵呵,是不是看到了?
Feb 19 00:07:35 gentux Hello, my LKM.
Feb 19 00:07:38 gentux Bye, my LKM.
模塊其它信息
比較常用信息常常包括:作者、描述、版權(quán)等,為此LKM為我們提供了如下宏:
MODULE_AUTHOR("author");
MODULE_DESCRIPTION("the description");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("dev"); // 設(shè)備驅(qū)動(dòng)程序所支持的設(shè)備。
比較常用的Free license有"GPL", "GPL v2", "GPL and additional rights", "Dual BSD/GPL", "Dual MPL/GPL"。
模塊參數(shù)
用戶空間的應(yīng)用程序可以接受用戶的參數(shù),LKM也可以做到,只是方式有些不同而已。相關(guān)的宏有:
MODULE_PARM(var, type);
MODULE_PARM_DESC(var, "the description of the var");
模塊參數(shù)的類型(即MODULE_PARM中的type)有一下幾種:

  • b byte(unsigned char)
  • h short
  • i int
  • l long
  • s string(char*)

這些參數(shù)最好有默認(rèn)值,如果有些必要參數(shù)用戶沒(méi)有設(shè)置可以通過(guò)在module_init指定的init函數(shù)返回負(fù)值來(lái)拒絕模塊的加載。 LKM還支持?jǐn)?shù)組類型的模塊,如果在類型符號(hào)前加上數(shù)字n則表示最大程度為n的數(shù)組,用“-”隔開(kāi)的數(shù)字分別代表最小和最大的數(shù)組長(zhǎng)度。
示例:
MODULE_PARM(var, "4i"); // 最大長(zhǎng)度為4的整形數(shù)組
MODULE_PARM(var, "2-6i"); // 最小長(zhǎng)度為2,最大長(zhǎng)度為6的整形數(shù)組
如何用insmod傳入?yún)?shù),其實(shí)man一下就可以了,不過(guò)現(xiàn)在的man有些過(guò)于簡(jiǎn)單,所以在此說(shuō)明一下:
insmod variable=value[,value2...] ...
其中value可以用引號(hào)括起來(lái),也可以不用。但是有一點(diǎn)“=”前后不能留有空格,并且value中也不能有空格。
模塊符號(hào)的導(dǎo)出
和用戶空間的應(yīng)用程序不同的是,引入一個(gè)模塊的目的常常是為了給內(nèi)核提供一些routine,來(lái)完成特定的功能,很少有模塊什么符號(hào)都不導(dǎo)出,為此Linux為用戶提供了如下宏:
EXPORT_SYMBOL(var); // 輸出symbol var
EXPORT_SYMBOL_GPL(var); // 輸出的symbol版權(quán)為GPL
模塊之間的依賴性
有的時(shí)候兩個(gè)模塊之間可能有依賴性,要加載的模塊A,依賴于模塊B,此時(shí)insmod是無(wú)能為力的,只能用modprobe來(lái)加載模塊和其依賴的模塊,否則只能手動(dòng)一個(gè)個(gè)加載。
modprobe通過(guò)讀取由depmod -a生成的/lib/modules/version/modules.dep來(lái)獲得其所依賴的模塊列表(也有可能是一個(gè)模塊樹(shù)),然后調(diào)用insmod來(lái)一個(gè)個(gè)按順序加載。
命名空間的問(wèn)題
  • 對(duì)于不需要export的全局symbol最好用static進(jìn)行修飾,限制其作用域?yàn)楸疚募,以防污染?nèi)核的命名空間。
  • 對(duì)于由內(nèi)核或其它模塊export的一些symbol,最好用extern進(jìn)行修飾,以示其不在本文件。
  • 在可能用到errno變量的場(chǎng)合,因?yàn)閮?nèi)核沒(méi)有export此symbol,只能有用戶自行定義,比如:int errno;
    一個(gè)較復(fù)雜的模塊示例/*file:    hello.c*/
    #ifndef __KERNEL__
    #define __KERNEL__
    #endif
    #ifndef MODULE
    #define MODULE
    #endif
    #include
    #include
    MODULE_AUTHOR("xiaosuo ");
    MODULE_LICENSE("GPL");
    MODULE_DESCRIPTION("This module is a example.");
    static int int_var = 0;
    static const char *str_var = "default";
    static int int_array[6];
    MODULE_PARM(int_var, "i");
    MODULE_PARM_DESC(int_var, "A integer variable");
    MODULE_PARM(str_var, "s");
    MODULE_PARM_DESC(str_var, "A string variable");
    MODULE_PARM(int_array, "2-6i");
    MODULE_PARM_DESC(int_array, "A integer array");
    static int __init hello_init(void)
    {
            int i;
            printk(KERN_ALERT "Hello, my LKM.\n");
            printk(KERN_ALERT "int_var %d.\n", int_var);
            printk(KERN_ALERT "str_var %s.\n", str_var);
            for(i = 0; i


    本文來(lái)自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u1/55468/showart_2151108.html
  • 您需要登錄后才可以回帖 登錄 | 注冊(cè)

    本版積分規(guī)則 發(fā)表回復(fù)

      

    北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
    未成年舉報(bào)專區(qū)
    中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
    感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

    清除 Cookies - ChinaUnix - Archiver - WAP - TOP