亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

第1個linux驅(qū)動___安裝驅(qū)動模塊之內(nèi)核再愛我一次

original 2016-11-16 09:51:10 562
abstrait:通過Makefile編譯得到first_drv.ko文件,這是一個可以被安裝到ubuntu中的驅(qū)動模塊,要怎樣做呢?在/work/my_drivers/first_drv/1th/目錄下執(zhí)行:insmod first_drv.ko如果你是在普通用戶狀態(tài)下執(zhí)行的這條命令,可以看到系統(tǒng)提醒我們:insmod: error inserting 'first_drv.ko': -1 Ope

通過Makefile編譯得到first_drv.ko文件,這是一個可以被安裝到ubuntu中的驅(qū)動模塊,要怎樣做呢?

在/work/my_drivers/first_drv/1th/目錄下執(zhí)行:insmod first_drv.ko

如果你是在普通用戶狀態(tài)下執(zhí)行的這條命令,可以看到系統(tǒng)提醒我們:insmod: error inserting 'first_drv.ko': -1 Operation not permitted

這是因為安裝驅(qū)動模塊需要超級權(quán)限,你可以在普通用戶狀態(tài)下執(zhí)行:sudo insmod first_drv.ko,或直接切換到root用戶,執(zhí)行insmod first_drv.ko

回車后發(fā)現(xiàn)什么事都沒有發(fā)生,其實在我們執(zhí)行insmod first_drv.ko的時候,就相當(dāng)于調(diào)用了first_drv.c中的module_init(first_drv_init),我們在以前的博文中說過module_init( )定義了一個結(jié)構(gòu)體,當(dāng)我們寫成module_init(first_drv_init)時,那個結(jié)構(gòu)體中就會有一個函數(shù)指針指向了first_drv_init函數(shù),從而跳轉(zhuǎn)執(zhí)行first_drv_init函數(shù)中的內(nèi)容:

static int __init first_drv_init(void)
{   
    printk(KERN_INFO"hello world!\n");
    return 0;
}

容易得知,該函數(shù)被調(diào)用時會打印出"hello world!",但是如果我們分析的沒錯的話,為何剛剛又沒有看到命令行中輸出"hello world!"呢?

可能有同學(xué)會想是不是打印級別的原因,于是輸入cat /proc/sys/kernel/printk,


打印:4       4       1       7


第一個果然是4,當(dāng)前打印級別"KERN_INFO"為6,因此改為7,即可讓"KERN_INFO"滿足打印出"hello world!"的打印級別,但事實上,即便改成7后,我們執(zhí)行insmod first_drv.ko后依舊看不出命令行中有任何動靜。

這是為什么呢?原來,ubuntu中嚴(yán)格限制printk輸出的數(shù)據(jù)顯示在命令行中,這內(nèi)部有一套機(jī)制使得我們不論如何設(shè)置打印級別,也看不到"hello world!"。

但好在我們可以通過執(zhí)行dmesg命令來查看ubuntu隱藏起來的內(nèi)核打印信息:


[   0.000000] Initializing cgroup subsys cpuset

[   0.000000] Initializing cgroup subsys cpu

···

[   0.000000] TSC: Frequency read from the hypervisor

[   0.000000] Detected 2501.000 MHz processor.

[   0.001144] Console: colour VGA+ 80x25

[  0.001146] console [tty0] enabled

···

[   2.665131] EXT4-fs: file extents enabled

[   2.666123] EXT4-fs: mballoc enabled

[   2.666135] EXT4-fs (sdb1): mounted filesystem with ordered data mode

[   2.737083] Installing knfsd (copyright (C) 1996 okir@monad.swb.de).

[   2.811797] eth4: link up

[   5.129212] svc: failed to register lockdv1 RPC service (errno 97).

[   5.129735] NFSD: Using /var/lib/nfs/v4recovery as the NFSv4 state recovery directory

[   5.129842] NFSD: starting 90-second grace period

[  14.218140] eth4: no IPv6 routers present

[ 979.436592] first_drv: module license 'unspecified' taints kernel.

[ 979.436620] Disabling lock debugging due to kernel taint

[ 979.437252] hello world!


最后三行打印信息是與我們安裝first_drv.ko驅(qū)動模塊相關(guān)的,我用紅色標(biāo)注了,而最后一行打印信息便是我們夢寐以求的"hello world!",這正是我們安裝驅(qū)動模塊的過程中成功調(diào)用了first_drv_init函數(shù)的鐵證。

我們的驅(qū)動模塊很簡單,除了我們手寫的"hello world!"和"goodbye world..."外再也沒有可能打印別的了,那么倒數(shù)第3行和倒數(shù)第2行是怎么回事?

這是因為在安裝驅(qū)動模塊的過程中,系統(tǒng)找不到驅(qū)動程序的許可證信息,還記得我們之前說first_drv.c這個驅(qū)動還有一個不足之處嗎,這就是它的不足之處,這就好像是你經(jīng)營一家餐館,但是沒有衛(wèi)生許可證,就算飯菜的味道再美味,顧客用餐還是會有點憂心忡忡。

其實說白了這種衛(wèi)生許可證只是一個形式,哪家的衛(wèi)生許可證都差不多,說到底這許可證和食物是否衛(wèi)生沒有必然的聯(lián)系,關(guān)鍵還是得看做飯菜的人有沒有注意衛(wèi)生。

我們的模塊許可證也是一樣,它與我們的程序沒有半點關(guān)系,程序?qū)懙迷僭愀?,只要加個模塊許可證,內(nèi)核便會一聲不吭地接納你,如果你代碼寫得再規(guī)范,唯獨丟了模塊許可證,那么內(nèi)核還是會嘟嚷幾句:"first_drv: module license 'unspecified' taints kernel."、"Disabling lock debugging due to kernel taint",不過驅(qū)動模塊還是能夠工作的,但為了更加符合內(nèi)核的要求,我們最好還是養(yǎng)成良好的習(xí)慣,加上模塊許可證,免得出現(xiàn)意想不到的麻煩。

我們只需要在first_drv.c最后再加一句:MODULE_LICENSE("GPL");即可。

符合內(nèi)核規(guī)范的first_drv.c如下所示:

#include <linux/module.h> 
#include <linux/init.h>
 
static int __init first_drv_init(void)
{   
    printk(KERN_INFO"hello world!\n");
    return 0;
}
 
static int __exit first_drv_exit(void)
{   
    printk(KERN_INFO"goodbye world...\n");
    return 0;
}
 
module_init(first_drv_init);
module_exit(first_drv_exit);
 
MODULE_LICENSE("GPL");

執(zhí)行make重新編譯first_drv.c,新生成的first_drv.ko即可覆蓋舊的first_drv.ko,因此不必每次都執(zhí)行make clean刪除舊文件。

但是舊的first_drv.ko還安裝在內(nèi)核上,在安裝新的first_drv.ko之前,我們?nèi)绾涡遁d舊的first_drv.ko呢。

執(zhí)行l(wèi)smod可以查看ubuntu中已經(jīng)安裝的驅(qū)動模塊,在打印出的一大頁信息的最上面可以看到:


Module                  Size  Used by

first_drv                1020  0 

binfmt_misc               8356  1 

nfsd                  241104  9 

exportfs                 4412  1 nfsd

nfs                   271880  0 

···

這說明first_drv驅(qū)動模塊還在內(nèi)核中,我們需要使用rmmod命令來卸載它:

執(zhí)行sudo rmmod first_drv或者sudo rmmod first_drv.ko(在root用戶狀態(tài)下不需要加sudo)

回車后一樣沒有任何事情發(fā)生,執(zhí)行dmesg可以看到最后一行多了:


[ 2333.481131] goodbye world...


這正是first_drv_exit函數(shù)中打印的"goodbye world...",與講解insmod first_drv.ko是一樣的原理,執(zhí)行rmmod first_drv.ko時,就相當(dāng)于去調(diào)用first_drv.c中的module_exit(first_drv_exit),然后調(diào)用first_drv_exit函數(shù),打印出"goodbye world..."信息。

其實ubuntu每次只會對沒有許可證的驅(qū)動模塊發(fā)出一次警告打印信息,對于同一個沒有許可證的驅(qū)動,即便卸載該驅(qū)動再重裝,ubuntu也不會再打印任何警告信息,似乎有一種對該驅(qū)動“徹底失望”的意味,為了讓系統(tǒng)重新認(rèn)識我們新的驅(qū)動程序,并確定在添加了許可證后內(nèi)核不會再打印警告信息,我們可以將ubuntu重啟,重啟后,在該目錄下執(zhí)行sudo insmod first_drv.ko后,再執(zhí)行dmesg打印驅(qū)動安裝信息:


...

[  5.714574] svc: failed to register lockdv1 RPC service (errno 97).

[  5.715109] NFSD: Using /var/lib/nfs/v4recovery as the NFSv4 state recovery directory

[   5.715371] NFSD: starting 90-second grace period

[  14.690813] eth4: no IPv6 routers present

[  89.383529] hello world!


只打印了"hello world!",可以證明添加了驅(qū)動模塊的"GPL"許可證后,ubuntu內(nèi)核已經(jīng)完全認(rèn)可了我們的驅(qū)動模塊first_drv。


Notes de version

Entrées populaires