女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

內核模塊的原理以及其模塊編寫

C語言專家集中營 ? 2018-01-02 11:11 ? 次閱讀

HelloWorld內核

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

什么是內核模塊

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

最簡單的內核模塊

#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"); } //一個模塊至少需要兩個函數,一個初始化函數這里是init_module在載入內核的時候調用, //一個結束函數,這里是cleannup_module在從內核中注銷的時候調用

一個Makefile來編譯這個內核模塊

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

注意:本文所有環節都是基于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進行編譯,編譯完就出現一個.ko的文件,這個就是內核模塊,需要載入運行

載入內核模塊進行運行

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

內核模塊編程和應用程序編程的異同

內核模塊編程是不能去使用標準庫(比如malloc free等)和一些第三方的庫

內核模塊編程是沒有內存保護的,如果內存訪問錯誤,就會出現oops錯誤

內核模塊編程是沒有main函數的,只有一個初始化函數,和一個提出函數

內核模塊編程需要使用內核提供的頭文件和API

內核模塊編程的標準輸出是輸出到文件,而不是輸出到屏幕

內核模塊編程的debug是不能使用gdb來進行調試的。

內核模塊進階

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

去掉init_module/cleanup_module

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

//不需要固定內核模塊的初始化函數的名字和結束的名字#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"); } //這兩個函數來注冊模塊初始化和模塊結束module_init(hello_2_init); module_exit(hello_2_exit);

__init/__initdata/__exit

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

模塊描述信息

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

[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

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

#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"); //模塊的作者MODULE_AUTHOR(DRIVER_AUTHOR); //模塊的描述MODULE_DESCRIPTION(DRIVER_DESC);

模塊參數

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

#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來對參數進行說明,指明這個參數的類型,權限等charp是字符指針//定義數組參數需要使用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);/* 載入模塊的時候,如果不指定參數就是上面的默認值,如果要指定參數的話 可以像下面這樣來指定參數。 insmod hello-5.ko mystring="superc" myint=444 */

模塊文件分割

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

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編譯的時候需要設置成這樣: 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

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • helloworld
    +關注

    關注

    0

    文章

    13

    瀏覽量

    4473
  • 內核模塊
    +關注

    關注

    0

    文章

    10

    瀏覽量

    3213

原文標題:黑客內核:編寫屬于你的Hello world

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

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    linux 了解內核模塊的原理 《Rice linux 學習開發》

    內核模塊是一種沒有經過鏈接,不能獨立運行的目標文件,是在內核空間中運行的程序。
    的頭像 發表于 07-16 10:08 ?4870次閱讀
    linux 了解<b class='flag-5'>內核模塊</b>的原理 《Rice linux 學習開發》

    Linux 內核模塊工作原理及內核模塊編譯案例

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

    詳解Linux內核模塊編寫方法

    Linux 系統為應用程序提供了功能強大且容易擴展的 API,但在某些情況下,這還遠遠不夠。與硬件交互或進行需要訪問系統中特權信息的操作時,就需要一個內核模塊
    的頭像 發表于 05-11 08:55 ?3936次閱讀

    Linux內核模塊間通訊方法

    Linux內核模塊間通訊方法非常的多,最便捷的方法莫過于函數或變量符號導出,然后直接調用。默認情況下,模塊模塊之間、模塊內核之間的全局變
    發表于 06-07 16:23 ?2968次閱讀
    Linux<b class='flag-5'>內核模塊</b>間通訊方法

    Linux內核模塊程序結構

    Linux設備驅動會以內核模塊的形式出現,因此,學會編寫Linux內核模塊編程是學習Linux設備驅動的先決條件。一個Linux內核模塊主要由如下幾個部分組成: (1)
    發表于 05-27 09:36

    高效學習Linux內核——內核模塊編譯

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

    什么是內核模塊?如何編寫一個簡單的模塊

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

    什么是 Linux 內核模塊?

    lsmod 命令能夠告訴你當前系統上加載了哪些內核模塊以及關于使用它們的一些有趣的細節。
    的頭像 發表于 08-09 17:01 ?3457次閱讀

    嵌入式LINUX系統內核內核模塊調試教程

    本文檔的主要內容詳細介紹的是嵌入式LINUX系統內核內核模塊調試教程。
    發表于 11-06 17:32 ?21次下載
    嵌入式LINUX系統<b class='flag-5'>內核</b>和<b class='flag-5'>內核模塊</b>調試教程

    如何在Petalinux創建Linux內核模塊

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

    Asterisk內核模塊介紹

    主要闡述Asterisk內核模塊的基礎知識。
    發表于 03-17 13:47 ?7次下載

    嵌入式LINUX系統內核內核模塊調試

    嵌入式LINUX系統內核內核模塊調試(嵌入式開發和硬件開發)-嵌入式LINUX系統內核內核模塊調試? ? ? ? ? ? ? ? ?
    發表于 07-30 13:55 ?10次下載
    嵌入式LINUX系統<b class='flag-5'>內核</b>和<b class='flag-5'>內核模塊</b>調試

    什么是內核模塊簽名?內核如何開啟模塊簽名

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

    Linux內核模塊參數傳遞與sysfs文件系統

    函數傳參的內核傳參機制,編寫內核程序時只要實現傳參接口,用戶在加載內核模塊時即可傳入指定參數,使得內核模塊更加靈活。
    發表于 06-07 16:23 ?2428次閱讀

    深入分析Linux kernel安全特性: 內核模塊簽名

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