Linux系統核心模組和驅動的編寫(轉)
Linux系統核心模組和驅動的編寫(轉)[@more@]Linux核心是一個整體是結構,因此向核心新增任何東西,或者刪除某些功能,都十分困難。為了解決這個問題引入了核心機制。從而可以動態的想核心中新增或者刪除模組。 模組不被編譯在核心中,因而控制了核心的大小.然而模組一旦被插入核心,他就和核心其他部分一樣.這樣一來就會曾家一部分系統開銷。同時,如果模組出現問題,也許會帶來系統的崩潰。 模組的實現機制: 啟動時,由函式 void inti_modules() 來初始化模組,因為啟動事很多時候沒有模組.這個函式往往把核心自身當作一個虛模組。 如由系統需要,則呼叫一系列以sys 開頭的函式,對模組進行操作. 如: sys_creat_modules(),sys_inti_modules() , sys_deldte_modules()等等. 這裡會用到一些模組的資料就結構,在/usr/scr/Linux/include/Linux/module.h 中,有興趣的朋友可以找出來一看塊的加入有兩種方法:一是手動加入:如:insmod modulename.另一種是根據需要,動態的載入模組:如你執行命令: $mount -t msdos /dev/hdd /mnt/d 時.系統便自動載入 FAT模組,以支援MSDOS的檔案系統。 1.模組程式設計 寫一個模組,必須有一定的多程式程式設計基礎,因為你變得程式不是以一個獨立的程式的來執行的。另外,因為,模組需要在核心模式下執行,會遇到在內和空間和使用者空間資料交換的問題.一般的資料複製函式無法完成這一個過程。因此係統已入了一些特殊的函式以用來完成核心空間和使用者空間資料的交換/ 這些函式有:void put _user (type valude,type *u_addr) memcpy_tofs() 等等,有興趣的朋友可以仔細的看看所有的函式,以及他們的用法.需要說明的是.模組程式設計河核心的版本有很大的關係。如果版本不通可能造成,核心模組不能編譯,或者.在執行這個模組時,出現不可測結果。如:系統崩潰等。 明白了這些以後,你就可以嘗試著編寫核心模組了。對於每一個核心模組來說,必定包含兩個函式int init_module() 這個函式在插入核心時啟動,在核心中註冊一定的功能函式,或者用他的程式碼代替內和中某些函式的內容(估計這些函式是空的)。因此,內和可以安全的解除安裝。 int cleanup_module() 當核心模組謝載時,呼叫.將模組從核心中清除. 同其他的程式設計教程一樣 ,我們給出一個hello world 的例子 /*hello.c a module programm*/ /* the program runing under kernel mod and it is a module*/ #include" Linux/kernerl.h" #include"lLinux/module.h" /* pross the CONFIG_MODVERSIONS*/ #if CONFIG_MODVERSIONS==1 #define MODVERSIONS #include""Linux/modversions.h" #end if /* the init function*/ int init_module() { printk(" hello world !
’); printd(" I have runing in a kerner mod@!!
"); return 1; } /* the distory function*/ int cleanup_module() { printk(" I will shut down myself in kernerl mod /n)"; retutn 0; } 這樣一個例子就完成了.我們也寫一個makefile 的例子,以適於我們在大程式重的應用。一下是makfile 檔案的內容 。 # a makefile for a module CC=gcc MODCFLAGS:= -Wall _DMODULE -D_KERNEL_ -DLinux hello.o hello.c /usr/inculde?Linux/version.h CC $(MODCFLAGS) 0c hello.c echo the module is complie completely 然後你執行make 命令 得到hello.o 這個模組,執行 $insmod hello.o hello world! I will shut down myself in kernerl mod $lsmod hello (unused) …. $remmod I will shut down myself in kernerl mod 這樣你的模組就可以隨意的插入和刪除了。 Linux中的大部分驅動程式,是以模組的形式編寫的,這些驅動程式原始碼可以修改到核心中,也可以把他們編譯成模組形勢,在需要的時候動態載入。 一個典型的驅動程式,大體上可以分為這麼幾個部分: 1.註冊裝置 在系統初啟,或者模組載入時候,必須將裝置登記到相應的裝置陣列,並返回裝置的主驅動號,例如:對快裝置來說呼叫 refister_blkdec() 將裝置新增到陣列blkdev中,並且獲得該裝置號,並利用這些裝置號對此陣列進行索引。對於字元驅動裝置來說,要使用 module_register_chrdev()來獲得祝裝置的驅動號,然後對這個裝置的所有呼叫都用這個裝置號來實現。 2.定義功能函式 對於每一個驅動函式來說,都有一些和此裝置密切相關的功能函式,那最常用的塊裝置或者字元裝置來說,都存在著諸如 open() read() write() ioctrol()這一類的操作。當系統社用這些呼叫時,將自動的使用驅動函式中特定的模組,來實現具體的操作。而對於特定的裝置,上面的系統呼叫對應的函式是一定的。 如:在塊驅動裝置中.當系統試圖讀取這個裝置(即呼叫read()時),就會執行驅動程式中的block_read() 這個函式。 開啟新裝置時會呼叫這個裝置驅動程式的device_open() 這個函式. 3.謝載模組 在不用這個裝置時,可以將他解除安裝,主要是從/proc 中取消這個裝置的特殊檔案,可用特定的函式實現。 下面我們列舉一個字元裝置驅動程式的框架.來說明這個過程. /* a module of a character device */ /* some include files*/ #include"param.h" #include"user.h" #include"tty.h" #include"dir.h" #include”fs.h" /* the include files modules need*/ #include"Linux/kernel.h" #include"Linux/module.h" #if CONFIG_MODBERSIONS==1 degine MODBERSIONS #include" Linux.modversions.h" #endif #difine devicename mydevice /* the init funcion*/ int init_module() { int tag=module_register_chrdev(0,mydevice,&Fops); if (tag<0) { printk("the device init is erro!
"); return 1; } return 0; } /*the funcion which the device will be used */ int device_open () { ……. } int device_read () { ……. } int device_write () { ……. } int device_ioctl () { ……. } …… /* the deltter function of this module*/ int cleanup_module() { int re=module_unregister_chrdev(tag,mydevice); if( re<0) { printk("erro unregister the module !!
"); return 1; } return 0; }
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8225414/viewspace-938637/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 在一個系統上編譯多個核心版本的驅動模組(轉)編譯
- 【linux】驅動-2-核心模組Linux
- Linux系統應用程式和核心模組的區別(轉)Linux
- Linux網路驅動程式編寫(四)(轉)Linux
- Linux網路驅動程式編寫(三)(轉)Linux
- Linux網路驅動程式編寫(二)(轉)Linux
- Linux網路驅動程式編寫(一)(轉)Linux
- Linux驅動開發筆記(一):helloworld驅動原始碼編寫、makefile編寫以及驅動編譯Linux筆記原始碼編譯
- Linux核心模組程式設計--系統呼叫(轉)Linux程式設計
- Linux RN6752 驅動編寫Linux
- 編寫屬於你的第一個Linux核心模組Linux
- Linux 核心驅動中對檔案的讀寫Linux
- 驅動篇——核心空間與核心模組
- Linux驅動實踐:如何編寫【 GPIO 】裝置的驅動程式?Linux
- Linux核心模組驅動載入與dmesg除錯Linux除錯
- Linux核心模組編譯Linux編譯
- Linux核心模組程式設計/proc 檔案系統(轉)Linux程式設計
- linux裝置驅動編寫入門Linux
- 如何編寫linux下nandflash驅動-4LinuxNaN
- linux裝置驅動編寫基礎Linux
- 用Mgaic Linux的核心和模組代替Debian的核心(轉)AILinux
- 入門文章:教你學會編寫Linux裝置驅動(轉)Linux
- Linux驅動之GPIO子系統和pinctrl子系統Linux
- 04_Linux下把驅動編譯進核心Linux編譯
- Linux系統可解除安裝核心模組完全指南(中)(轉)Linux
- Linux系統可解除安裝核心模組完全指南(下)(轉)Linux
- Linux系統可解除安裝核心模組完全指南(1)(轉)Linux
- Linux系統可解除安裝核心模組完全指南(2)(轉)Linux
- Linux系統可解除安裝核心模組完全指南(3)(轉)Linux
- 用 Delphi 編寫 VxD 裝置驅動程式(轉) (轉)
- 如何編寫一個簡單的Linux驅動(三)——完善裝置驅動Linux
- linux 觸控式螢幕驅動編寫Linux
- Windows95的裝置驅動程式的編寫 (轉)Windows
- Linux作業系統核心編譯詳解(2)(轉)Linux作業系統編譯
- 高效學習Linux核心——核心模組編譯Linux編譯
- 核心必須懂(四): 撰寫核心驅動
- 編譯安裝最新的Linux系統核心編譯Linux
- 【轉】編譯Android系統原始碼和核心原始碼編譯Android原始碼