chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

內(nèi)核模塊的原理以及其模塊編寫

C語言專家集中營 ? 2018-01-02 11:11 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

HelloWorld內(nèi)核

開始斷斷續(xù)續(xù)學(xué)習(xí)內(nèi)核,大概半年了,多少開始對內(nèi)核有點感悟了,但是對于這個龐然大物我顯得很渺小,在枯燥的內(nèi)核源碼之中似乎沒有一點點成功的喜悅,因此我選擇學(xué)習(xí)內(nèi)核模塊編程,通過編寫一些內(nèi)核模塊來體驗?zāi)且稽c點小小的成就感吧!

什么是內(nèi)核模塊

內(nèi)核模塊是具有獨立功能的程序。它可以被單獨編譯,但是不能單獨運行,它的運行必須被鏈接到內(nèi)核作為內(nèi)核的一部分在內(nèi)核空間中運行。
內(nèi)核模塊的原理以及其模塊編寫

最簡單的內(nèi)核模塊

#include //所有模塊都必須包含的頭文件#include //一些宏定義,例如這里的KERN_INFOint init_module(void) { printk(KERN_INFO "Hello world 1.\n"); /* * 返回非0表示模塊初始化失敗,無法載入 */ return 0; }void cleanup_module(void) { printk(KERN_INFO "Goodbye world 1.\n"); } //一個模塊至少需要兩個函數(shù),一個初始化函數(shù)這里是init_module在載入內(nèi)核的時候調(diào)用, //一個結(jié)束函數(shù),這里是cleannup_module在從內(nèi)核中注銷的時候調(diào)用

一個Makefile來編譯這個內(nèi)核模塊

obj-m += hello-1.oall: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

注意:本文所有環(huán)節(jié)都是基于Centos6.5下測試OK,你可能在有的書上看見Makefile是這樣寫的

make -C /usr/src/linux-headers-$(shell uname -r) M=$(PWD) modules 其實/lib/modules/$(shell uname -r)/build 這個路徑就是上面路徑的一個軟鏈接 [root@localhost 2.6.32-431.el6.x86_64]# ls -al build lrwxrwxrwx. 1 root root 44 Mar 16 05:26 build -> /usr/src/kernels/2.6.32-504.12.2.el6.x86_64/

編寫好makefile文件后,使用make進(jìn)行編譯,編譯完就出現(xiàn)一個.ko的文件,這個就是內(nèi)核模塊,需要載入運行

載入內(nèi)核模塊進(jìn)行運行

載入內(nèi)核模塊的方法有很多比如: modprobe 和 insmod前者會分析模塊的依賴關(guān)系,并且會去指定路徑查找內(nèi)核模塊載入,而后者需要指定內(nèi)核模塊的絕對路徑進(jìn)行載入并且不解決模塊的依賴關(guān)系。這里我們使用insmod來載入內(nèi)核模塊,使用rmmod卸載內(nèi)核模塊 [root@localhost kernel_module]# insmod hello-1.ko使用dmes查看內(nèi)核模塊的輸出Hello world 1.卸載內(nèi)核模塊 [root@localhost kernel_module]# rmmod hello-1 dmesg查看輸出Goodbye world 1.

內(nèi)核模塊編程和應(yīng)用程序編程的異同

內(nèi)核模塊編程是不能去使用標(biāo)準(zhǔn)庫(比如malloc free等)和一些第三方的庫

內(nèi)核模塊編程是沒有內(nèi)存保護(hù)的,如果內(nèi)存訪問錯誤,就會出現(xiàn)oops錯誤

內(nèi)核模塊編程是沒有main函數(shù)的,只有一個初始化函數(shù),和一個提出函數(shù)

內(nèi)核模塊編程需要使用內(nèi)核提供的頭文件和API

內(nèi)核模塊編程的標(biāo)準(zhǔn)輸出是輸出到文件,而不是輸出到屏幕

內(nèi)核模塊編程的debug是不能使用gdb來進(jìn)行調(diào)試的。

內(nèi)核模塊進(jìn)階

內(nèi)核模塊的編程不僅僅是上面的一個HelloWorld,內(nèi)核模塊編程還有一些更高級的寫法,下面會一一介紹:

去掉init_module/cleanup_module

在上面的HelloWorld模塊中,你會發(fā)現(xiàn)初始化函數(shù)和退出函數(shù)好像是固定的名稱,那么有沒有辦法自己自定義名稱呢其實是可以的,你可以自己自定義名稱,然后進(jìn)行注冊即可(注冊其實就是做了一個函數(shù)指針的賦值而已)下面是自定義名稱的寫法:

//不需要固定內(nèi)核模塊的初始化函數(shù)的名字和結(jié)束的名字#include #include #include static int hello_2_init(void) { printk(KERN_INFO "Hello,world 2\n"); return 0; }static void hello_2_exit(void) { printk(KERN_INFO "Goodbye,world 2\n"); } //這兩個函數(shù)來注冊模塊初始化和模塊結(jié)束module_init(hello_2_init); module_exit(hello_2_exit);

__init/__initdata/__exit

在有的內(nèi)核模塊編程的書籍或者介紹內(nèi)核模塊編程的博客中,你或許會發(fā)現(xiàn)有這樣的一些特殊關(guān)鍵字__init ,_initdata ,__exit等等,其實這些都是gcc的擴(kuò)展屬性:__init宏最常用的地方是驅(qū)動模塊初始化函數(shù)的定義處,其目的是將驅(qū)動模塊的初始化函數(shù)放入名叫.init.text的輸入段。當(dāng)內(nèi)核啟動完畢后,這個段中的內(nèi)存會被釋放掉供其他使用。__initdata宏用于數(shù)據(jù)定義,目的是將數(shù)據(jù)放入名叫.init.data的輸入段。其它幾個宏也類似。

模塊描述信息

可以使用modinfo去查看一個模塊的模塊信息,下面是自己編寫的模塊和系統(tǒng)自帶的模塊的兩個模塊信息的對比

[root@localhost kernel_module]# modinfo hello-1.kofilename: hello-1.kosrcversion: 0D3956C127A907CC9E7114Fdepends: vermagic: 2.6.32-504.12.2.el6.x86_64 SMP mod_unload modversions [root@localhost kernel_module]# modinfo/lib/modules/2.6.32-431.el6.x86_64/kernel/fs/ext4/ext4.ko filename: /lib/modules/2.6.32-431.el6.x86_64/kernel/fs/ext4/ext4.kolicense: GPLdescription: Fourth Extended Filesystemauthor: Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others srcversion: 345EBDA2AEFF60FFED78864 depends: mbcache,jbd2 vermagic: 2.6.32-431.el6.x86_64 SMP mod_unload modversions

從上面的對比可知,自己編寫的模塊的模塊信息很少,沒有作者信息,沒有許可證信息等等,其實這些都可以設(shè)置

#include #include #include #define DRIVER_AUTHOR "zyf"#define DRIVER_DESC "A sample driver"static int __init init_hello_4(void) { printk(KERN_INFO "Hello, world 4\n"); return 0; } static void __exit cleanup_hello_4(void) { printk(KERN_INFO "Goodbye, world 4\n"); } module_init(init_hello_4); module_exit(cleanup_hello_4); //模塊的許可證 MODULE_LICENSE("GPL"); //模塊的作者M(jìn)ODULE_AUTHOR(DRIVER_AUTHOR); //模塊的描述MODULE_DESCRIPTION(DRIVER_DESC);

模塊參數(shù)

在用戶態(tài)編寫程序的時候我們都應(yīng)該清楚,是可以給程序傳遞參數(shù)的,那么同樣內(nèi)核模塊同樣也有這樣的需求,下面的例子展示了如何去給內(nèi)核模塊傳遞參數(shù):

#include #include #include #include #include MODULE_LICENSE("GPL"); MODULE_AUTHOR("ZYF");static short int myshort = 1;static int myint = 420;static long int mylong = 9999;static char *mystring = "blah";static int myintArray[2] = {-1,-1};static int arr_argc = 0;//需要使用module_param來對參數(shù)進(jìn)行說明,指明這個參數(shù)的類型,權(quán)限等charp是字符指針//定義數(shù)組參數(shù)需要使用module_param_arraymodule_param(myshort,short,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP); MODULE_PARM_DESC(myshort,"A short integer"); module_param(myint,int,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); MODULE_PARM_DESC(myint,"A integer"); module_param(mylong,long,S_IRUSR); MODULE_PARM_DESC(mylong,"A long integer"); module_param(mystring,charp,0000); MODULE_PARM_DESC(mystring,"A character string"); module_param_array(myintArray,int,&arr_argc,0000); MODULE_PARM_DESC(myintArray,"An array of integer");static int __init hello_5_init(void) { int i; printk(KERN_INFO "Hello, world 5\n=============\n"); printk(KERN_INFO "myshort is a short integer: %hd\n", myshort); printk(KERN_INFO "myint is an integer: %d\n", myint); printk(KERN_INFO "mylong is a long integer: %ld\n", mylong); printk(KERN_INFO "mystring is a string: %s\n", mystring); for (i = 0; i < (sizeof myintArray / sizeof (int)); i++) ? ?{ ? ? ? ?printk(KERN_INFO "myintArray[%d] = %d\n", i, myintArray[i]); ? ?} ? ?printk(KERN_INFO "got %d arguments for myintArray.\n", arr_argc); ? ? ? ?return 0; }static void __exit hello_5_exit(void) { ? ?printk(KERN_INFO "Goodbye,world 5\n"); } module_init(hello_5_init); module_exit(hello_5_exit);/* 載入模塊的時候,如果不指定參數(shù)就是上面的默認(rèn)值,如果要指定參數(shù)的話 可以像下面這樣來指定參數(shù)。 insmod hello-5.ko mystring="superc" myint=444 */

模塊文件分割

在用戶態(tài)寫程序的時候,你會將一個大的程序分割成好幾個文件,這樣程序脈絡(luò)就顯的很清晰。在這里我們將初始化函數(shù)和退出函數(shù)分開在兩個文件中編寫。

start.c中#include /* We're doing kernel work */#include /* Specifically, a module */int init_module(void) { printk(KERN_INFO "Hello, world - this is the kernel speaking\n"); return 0; } stop.c中#include /* We're doing kernel work */#include /* Specifically, a module */void cleanup_module() { printk(KERN_INFO "Short is the life of a kernel module\n"); } 那么Makefile編譯的時候需要設(shè)置成這樣: obj-m += startstop.o startstop-objs := start.o stop.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • helloworld
    +關(guān)注

    關(guān)注

    0

    文章

    13

    瀏覽量

    4601
  • 內(nèi)核模塊
    +關(guān)注

    關(guān)注

    0

    文章

    10

    瀏覽量

    3504

原文標(biāo)題:黑客內(nèi)核:編寫屬于你的Hello world

文章出處:【微信號:C_Expert,微信公眾號:C語言專家集中營】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    linux 了解內(nèi)核模塊的原理 《Rice linux 學(xué)習(xí)開發(fā)》

    內(nèi)核模塊是一種沒有經(jīng)過鏈接,不能獨立運行的目標(biāo)文件,是在內(nèi)核空間中運行的程序。
    的頭像 發(fā)表于 07-16 10:08 ?5045次閱讀
    linux 了解<b class='flag-5'>內(nèi)核模塊</b>的原理 《Rice linux 學(xué)習(xí)開發(fā)》

    Linux 內(nèi)核模塊工作原理及內(nèi)核模塊編譯案例

    一個內(nèi)核模塊至少包含兩個函數(shù),模塊被加載時執(zhí)行的初始化函數(shù)init_module()和模塊被卸載時執(zhí)行的結(jié)束函數(shù)cleanup_module()。
    發(fā)表于 09-23 09:39 ?2884次閱讀
    Linux <b class='flag-5'>內(nèi)核模塊</b>工作原理及<b class='flag-5'>內(nèi)核模塊</b>編譯案例

    詳解Linux內(nèi)核模塊編寫方法

    Linux 系統(tǒng)為應(yīng)用程序提供了功能強(qiáng)大且容易擴(kuò)展的 API,但在某些情況下,這還遠(yuǎn)遠(yuǎn)不夠。與硬件交互或進(jìn)行需要訪問系統(tǒng)中特權(quán)信息的操作時,就需要一個內(nèi)核模塊。
    的頭像 發(fā)表于 05-11 08:55 ?4137次閱讀

    Linux內(nèi)核模塊間通訊方法

    Linux內(nèi)核模塊間通訊方法非常的多,最便捷的方法莫過于函數(shù)或變量符號導(dǎo)出,然后直接調(diào)用。默認(rèn)情況下,模塊模塊之間、模塊內(nèi)核之間的全局變
    發(fā)表于 06-07 16:23 ?3354次閱讀
    Linux<b class='flag-5'>內(nèi)核模塊</b>間通訊方法

    Linux內(nèi)核模塊程序結(jié)構(gòu)

    Linux設(shè)備驅(qū)動會以內(nèi)核模塊的形式出現(xiàn),因此,學(xué)會編寫Linux內(nèi)核模塊編程是學(xué)習(xí)Linux設(shè)備驅(qū)動的先決條件。一個Linux內(nèi)核模塊主要由如下幾個部分組成: (1)
    發(fā)表于 05-27 09:36

    高效學(xué)習(xí)Linux內(nèi)核——內(nèi)核模塊編譯

    (description);三、Linux內(nèi)核模塊的編譯首先為HelloWorld模塊編寫MakeFile文件該MakeFile文件應(yīng)該與源碼位于同一目錄在Makefile中,在obj-m
    發(fā)表于 09-24 09:11

    什么是內(nèi)核模塊?如何編寫一個簡單的模塊

    內(nèi)核模塊是Linux內(nèi)核向外部提供的一個插口,其全稱為動態(tài)可加載內(nèi)核模塊(Loadable Kernel Module,LKM),我們簡稱為模塊。Linux
    發(fā)表于 08-24 17:15 ?20次下載

    什么是 Linux 內(nèi)核模塊?

    lsmod 命令能夠告訴你當(dāng)前系統(tǒng)上加載了哪些內(nèi)核模塊,以及關(guān)于使用它們的一些有趣的細(xì)節(jié)。
    的頭像 發(fā)表于 08-09 17:01 ?3682次閱讀

    嵌入式LINUX系統(tǒng)內(nèi)核內(nèi)核模塊調(diào)試教程

    本文檔的主要內(nèi)容詳細(xì)介紹的是嵌入式LINUX系統(tǒng)內(nèi)核內(nèi)核模塊調(diào)試教程。
    發(fā)表于 11-06 17:32 ?21次下載
    嵌入式LINUX系統(tǒng)<b class='flag-5'>內(nèi)核</b>和<b class='flag-5'>內(nèi)核模塊</b>調(diào)試教程

    如何在Petalinux創(chuàng)建Linux內(nèi)核模塊?

    創(chuàng)建內(nèi)核模塊 Petalinux可以幫助工程師簡化內(nèi)核模塊的創(chuàng)建工作。在petalinux工程目錄下,使用命令“ petalinux-create -t modules --name
    的頭像 發(fā)表于 03-02 11:10 ?5158次閱讀

    Asterisk內(nèi)核模塊介紹

    主要闡述Asterisk內(nèi)核模塊的基礎(chǔ)知識。
    發(fā)表于 03-17 13:47 ?7次下載

    嵌入式LINUX系統(tǒng)內(nèi)核內(nèi)核模塊調(diào)試

    嵌入式LINUX系統(tǒng)內(nèi)核內(nèi)核模塊調(diào)試(嵌入式開發(fā)和硬件開發(fā))-嵌入式LINUX系統(tǒng)內(nèi)核內(nèi)核模塊調(diào)試? ? ? ? ? ? ? ? ?
    發(fā)表于 07-30 13:55 ?10次下載
    嵌入式LINUX系統(tǒng)<b class='flag-5'>內(nèi)核</b>和<b class='flag-5'>內(nèi)核模塊</b>調(diào)試

    什么是內(nèi)核模塊簽名?內(nèi)核如何開啟模塊簽名

    驅(qū)動可以直接編譯進(jìn)內(nèi)核鏡像,也可以單獨編譯成ko文件(內(nèi)核模塊),然后再進(jìn)行加載。內(nèi)核從3.7后開始支持模塊簽名,該功能使能以后,內(nèi)核只允許
    發(fā)表于 08-08 16:14 ?1917次閱讀

    Linux內(nèi)核模塊參數(shù)傳遞與sysfs文件系統(tǒng)

    函數(shù)傳參的內(nèi)核傳參機(jī)制,編寫內(nèi)核程序時只要實現(xiàn)傳參接口,用戶在加載內(nèi)核模塊時即可傳入指定參數(shù),使得內(nèi)核模塊更加靈活。
    發(fā)表于 06-07 16:23 ?2669次閱讀

    深入分析Linux kernel安全特性: 內(nèi)核模塊簽名

    顧名思義,在開啟該功能之后,內(nèi)核在加載內(nèi)核模塊時,會對內(nèi)核模塊的簽名進(jìn)行檢查。
    的頭像 發(fā)表于 10-18 12:32 ?7457次閱讀