




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
如果你對內核驅動模塊一無所知,請先學習內核驅動模塊的基礎知識。如果你已經入門了內核驅動模塊,但是仍感覺有些模糊,不能從整體來了解一個內核驅動模塊的結構,請賞讀一下這篇拙文。如果你已經從事內核模塊編程N年,并且道行高深,也請不吝賜教一下文中的疏漏錯誤。本文中我將實現一個簡單的Linux字符設備,旨在大致勾勒出linux內核模塊的編寫方法的輪廓。其中重點介紹ioctl的用途。我把這個簡單的Linux字符設備模塊命名為hello_mod.設備類型名為hello_class設備名為hello該設備是一個虛擬設備,模塊加載時會在/sys/class/中創(chuàng)建名為hello_class的邏輯設備,在/dev/中創(chuàng)建hello的物理設備文件。模塊名為hello_mod,可接受輸入字符串數據(長度小于128),處理該輸入字符串之后可向外輸出字符串。并且可以接受ioctl()函數控制內部處理字符串的方式。例如:通過write函數寫入“Tom”,通過ioctl函數設置langtype二Chinese,通過read函數讀出的數據將會是“你好!Tom/n”通過write函數寫入“Tom”,通過ioctl函數設置langtype二english,通過read函數讀出的數據將會是“hello!Tom/n”通過write函數寫入“Tom”,通過ioctl函數設置langtype二pinyin,通過read函數讀出的數據將會是“nihao!Tom/n”一般的內核模塊中不會負責設備類別和節(jié)點的創(chuàng)建,我們在編譯完之后會得到.?;蛘?ko文件,然后insmod之后需要mknod來創(chuàng)建相應文件,這個簡單的例子中我們讓驅動模塊加載時負責自動創(chuàng)建設備類別和設備文件。這個功能有兩個步驟,創(chuàng)建設備類別文件class_create();創(chuàng)建設備文件device_create();關于這兩個函數的使用方法請參閱其他資料。linux設備驅動的編寫相對windows編程來說更容易理解一點因為不需要處理IRP,應用層函數和內核函數的關聯方式淺顯易懂。比如當應曾函數對我的設備調用了open()函數,而最終這個應用層函數會調用我的設備中的自定義open()函數,這個函數要怎么寫呢,我在我的設備中定義的函數名是hello_mod_open,注意函數名是可以隨意定義,但是函數簽名是要符合內核要求的,具體的定義是怎么樣請看<linux/fs.h>staticinthello_mod_open(structinode*,structfile*);這樣就定義了內核中的open函數,這只是定義還需要與我們自己的模塊關聯起來,這就要用到一個結構structfile_operations這個結構里面的成員是對應于設備操作的各種函數的指針。我在設備中用到了這些函數所以就如下定義,注意下面的寫法不是標準ANSIC的語法,而是GNU擴展語法。structfile_operationshello_mod_fops={.owner=THIS_MODULE,.open=hello_mod_open,.read=hello_mod_read,.write=hello_mod_write,.ioctl=hello_mod_ioctl,.release=hello_mod_release,這個結構體變量定義好之后我們在模塊初始化函數中就可以通過register_chrdev()或者填充cdev結構來關聯所有的操作到我們的模塊函數了。和設備交互的數據我們總稱為''數據”,但是大致可劃分為兩種“功能數據”:我們要輸入設備處理的和設備處理完之后輸出的數據?!翱刂茢祿保何覀冇脕砜刂圃O備特性功能的命令和參數。open,read,write,release等函數是對一個驅動模塊的使用,就是我們對“設備的功能”的使用。但是一個設備有可能有很多功能,那么我們要怎么控制設備讓設備完成指定的功能呢?據個例子來說:假如我們有一個翻譯機(姑且說機吧,也可能是器)實體設備,主要功能是輸入中文,然后可以輸出各種語言對應的翻譯結果,那這個機的功能就是翻譯,我們真正用來處理的數據是我們輸入的中文,我們要得到的“設備功能''就是翻譯后的輸出內容,而各種語言則是我們的選擇控制了,我們可設定這個設備翻譯成何種語言。這就要求我們要向設備發(fā)送命令,設定目標語言。請注意我們要發(fā)送的是兩個“控制數據”,命令和參數。命令:一個設備可能有很多種行為,我們的命令就是代表我們要讓設備執(zhí)行何種行為?!皬臀弧?,“設定目標語言”,“獲得當前目標語言'等參數:對于某一個命令,可能需要參數可能不需要參數。比如:“復位”命令就不需要參數?!霸O定目標語言”則需要傳入目標語言的類型?!矮@取目標語言”則需要傳入一個能夠接收目標語言類型的參數。自己畫了一個設備“數據流”圖,希望能加深理解。設備數據流^-tishion需要處理的數據writef)設備控制參數^-ioctlQ一.設備_-而1(一設備控制命令和參數i
readQ.如理之后的數據對于我們自己的設備我們就要自己定義設備命令了,如果你要想搞清命令的格式,請參考其他資料關于ioctl的參數的介紹。這里不打算介紹這個,只介紹ioctl實際功能。定義自己的IO控制命令需要用到宏。這里直接寫出我的定義而不是介紹宏的實現#defineHELLO_MAGIC12#defineHELLO_IOCTL_RESETLANG_IO(HELLO_MAGIC,0)//設置復位,這個命令不帶參數#defineHELLO_IOCTL_GETLANG_IOR(HELLO_MAGIC,1,int)//獲取當前設備的語言類型參數,參數是int型#defineHELLO_IOCTL_SETLANG_IOW(HELLO_MAGIC,2,int)//設置設備的語言類型,參數是int型多的不說了,下面貼上完整代碼,懶人沒寫注釋。。不好意思。hello_mod.c[cpp]viewplaincopyprint?TOC\o"1-5"\h\z/***4.*Filename:hello.c5.*6.*Description:hello_mod7.*8.*Version:1.09.*Created:01/28/201105:07:55PM10.*Revision:none11.*Compiler:gcc12.*13.*Author:Tishion(shion),tishion@163.com14.*Company:LIM15.*16.*=====================================================================================17.*/18.19.20.#include<linux/module.h>21.#include<linux/init.h>22.#include<linux/kernel.h>23.#include<linux/fs.h>24.#include<linux/uaccess.h>25.#include<linux/semaphore.h>26.#include<linux/cdev.h>27.#include<linux/device.h>28.#include<linux/ioctl.h>29.#include<linux/slab.h>30.#include<linux/errno.h>31.#include<linux/string.h>32.#include"hellomodioctl.h"33.
34.#defineMAJOR_NUM25035.#defineMINOR_NUM036.#defineIN_BUF_LEN25637.#defineOUTBUFLEN51238.39.MODULE_AUTHOR("Tishion");40.MODULE_DESCRIPTION("Hello_moddriverbytishion");41.42.staticstructclass*hello_class;43.staticstructcdevhello_cdev;44.staticdev_tdevnum=0;45.staticchar*modname="hello_mod";46.staticchar*devicename="hello";47.staticchar*classname="hello_class";48.49.staticintopen_count=0;50.staticstructsemaphoresem;51.staticspinlock_tspin=SPIN_LOCK_UNLOCKED;52.staticchar*inbuffer=NULL;53.staticchar*outbuffer=NULL;54.staticlang_tlangtype;55.56.staticinthello_mod_open(structinode*,structfile*);57.staticinthello_mod_release(structinode*,structfile*);58.staticssize_thello_mod_read(structfile*,char*,size_t,loff_t*);59.staticssize_thello_mod_write(structfile*,constchar*,size_t,loff_t*);60.staticinthello_mod_ioctl(structinode*,structfile*,unsignedint,unsignedlong);61.62.structfile_operationshello_mod_fops=63.{64..owner=THIS_MODULE,65..open=hello_mod_open,66..read=hello_mod_read,67..write=hello_mod_write,68..ioctl=hello_mod_ioctl,69..release=hello_mod_release,70.};71.72.staticinthello_mod_open(structinode*inode,structfile*pfile)73.{74.printk("+hello_mod_open()!/n");75.spin_lock(&spin);76.if(open_count)77.{78.spin_unlock(&spin);
79.return-EBUSY;80.}81.open_count++;82.spin_unlock(&spin);83.printk("-hello_mod_open()!/n");84.return0;85.}86.staticinthello_mod_release(structinode*inode,structfile*pfile)87.{88.printk("+hello_mod_release()!/n");89.open_count--;90.printk("-hello_mod_release()!/n");91.return0;92.}93.staticssize_thello_mod_read(structfile*pfile,char*user_buf,size_tlen,loff_t*off)94.{95.printk("+hello_mod_read()!/n");96.97.if(down_interruptible(&sem))98.{99.return-ERESTARTSYS;100.}101.memset(outbuffer,0,OUT_BUF_LEN);102.printk("+switch()/n");103.switch(langtype)104.{105.caseenglish:106.printk(">incase:english/n");107.sprintf(outbuffer,"Hello!%s.",inbuffer);108.break;109.casechinese:110.printk(">incase:chinese/n");111.sprintf(outbuffer,"你好!%s.",inbuffer);112.break;113.casepinyin:114.printk(">incase:pinyin/n");115.sprintf(outbuffer,"nihao!%s.",inbuffer);116.break;117.default:118.printk(">incase:default/n");119.break;120.}121.printk("-switch()/n");122.if(copy_to_user(user_buf,outbuffer,len))123.{
124.up(&sem);125.return-EFAULT;126.}127.up(&sem);128.printk("-hello_mod_read()!/n");129.return0;130.}131.staticssize_thello_mod_write(structfile*pfile,constchar*user_buf,size_tlen,loff_t*off)132.{133.printk("+hello_mod_write()!/n");134.if(down_interruptible(&sem))135.{136.return-ERESTARTSYS;137.}138.if(len>IN_BUF_LEN)139.{140.printk("Outofinputbuffer/n");141.return-ERESTARTSYS;142.}143.if(copy_from_user(inbuffer,user_buf,len))144.{145.up(&sem);146.return-EFAULT;147.}148.up(&sem);149.printk("-hello_mod_write()!/n");150.return0;151.}152.staticinthello_mod_ioctl(structinode*inode,structfile*pfile,unsignedintcmd,unsignedlongarg)153.{154.interr=0;155.printk("+hello_mod_ioctl()!/n");156.printk("+switch()/n");157.switch(cmd)158.{159.caseHELLO_IOCTL_RESETLANG:160.printk(">incase:HELLO_IOCTL_RESETLANG/n");161.langtype=english;162.break;163.caseHELLO_IOCTL_GETLANG:164.printk(">incase:HELLO_IOCTL_GETLANG/n");165.err=copy_to_user((int*)arg,&langtype,sizeof(int));166.break;167.caseHELLO_IOCTL_SETLANG:168.printk(">incase:HELLO_IOCTL_SETLANG/n");
169.err=copy_from_user(&langtype,(int*)arg,sizeof(int));170.break;171.default:172.printk(">incase:default/n");173.err=ENOTSUPP;174.break;175.}176.printk("-switch()/n");177.printk("-hello_mod_ioctl()!/n");178.returnerr;179.}180.staticint_inithello_mod_init(void)181.{182.intresult;183.printk("+hello_mod_init()!/n");184.devnum=MKDEV(MAJOR_NUM,MINOR_NUM);185.result=register_chrdev_region(devnum,1,modname);186.187.if(result<0)188.{189.printk("hello_mod:can'tgetmajornumber!/n");190.returnresult;191.}192.193.cdev_init(&hello_cdev,&hello_mod_fops);194.hello_cdev.owner=THIS_MODULE;195.hello_cdev.ops=&hello_mod_fops;196.result=cdev_add(&hello_cdev,devnum,1);197.if(result)198.printk("Failedatcdev_add()");199.hello_class=class_create(THIS_MODULE,classname);200.if(IS_ERR(hello_class))201.{202.printk("Failedatclass_create().Pleaseexec[mknod]beforeoperatethedevice/n");203.}204.else205.{206.device_create(hello_class,NULL,devnum,NULL,devicename);207.}208.209.open_count=0;210.langtype=english;211.inbuffer=(char*)kmalloc(IN_BUF_LEN,GFP_KERNEL);212.outbuffer=(char*)kmalloc(OUT_BUF_LEN,GFP_KERNEL);213.init_MUTEX(&sem);printk("-hello_mod_init()!/n");return0;}217.staticvoid_exithello_mod_exit(void){printk("+hello_mod_exit!/n");kfree(inbuffer);kfree(outbuffer);cdev_del(&hello_cdev);device_destroy(hello_class,devnum);class_destroy(hello_class);unregister_chrdev_region(devnum,1);printk("-hello_mod_exit!/n");return;}230.module_init(hello_mod_init);module_exit(hello_mod_exit);MODULE_LICENSE("GPL");hello_mod_iotcl.h[cpp]viewplaincopyprint?TOC\o"1-5"\h\z/**=====================================================================================**Filename:hello_mod_ioctl.h**Description:definethecmdsupportedbyhello_mod**Version:1.0*Created:06/19/201110:24:20PM10.*Revision:none11.*Compiler:gcc12.*13.*Author:Tishion(shion),tishion@163.com14.*Company:LIM15.**=====17.*/18.19.#ifndefHELLOMOD_IOCTL_H_#define__HELLO_MOD_IOCTL_H21.#defineHELLO_MAGIC1223.#defineHELLO_IOCTL_RESETLANG_IO(HELLO_MAGIC,0)//setlangtype=english24.#defineHELLO_IOCTL_GETLANG_IOR(HELLO_MAGIC,1,int)//getlangtype25.#defineHELLO_IOCTL_SETLANG_IOW(HELLO_MAGIC,2,int)//setlangtype26.typedefenum_lang_t{english,Chinese,pinyin}lang_t;31.#endifMakefile[cpp]viewplaincopyprint?#**********************************************#Makefilelinux2.6Module#ThismakefileiswrittenforUbuntu10.10#Itmaynotperfomancewithouterrosonthe#otherversionordistributions.#**********************************************#BY:tishion#Mail:tishion@163.com#2011/06/19********************************************obj-m+=hello_mod.oCURRENT_PATH:=$(shellpwd)LINUX_KERNEL:=$(shelluname-r)LINUX_KERNEL_PATH:=/usr/src/linux-headers-all:make-C$(LINUX_KERNEL_PATH)M=$(CURRENTclean:make-C$(LINUX_KERNEL_PATH)M=$(CURRENTinstall:insmodhello_mod.kounistall:rmmodhellomod***$(LINUX_KERNEL)_PATH)modules_PATH)clean附上一用戶房測試文件,編譯后需要root身份執(zhí)行.
[cpp]viewplaincopyprint?1./*3.*4.*Filename:hell_mod_test.c5.*6.*Description:hell_modtestapp7.*8.*Version:1.09.*Created:06/20/201101:44:11AM10.*Revision:none11.*Compiler:gcc12.*13.*Author:Tishion(shion),tishion@163.com14.*Company:LIM15.**=========================================17.*/18.19.#include<stdio.h>20.#include<sys/types.h>21.#include<sys/stat.h>22.#include<fcntl.h>23.#include<unistd.h>24.#include<linux/ioctl.h>25.#include<string.h>26.#include<errno.h>27.#include"../hello_mod_ioctl.h"28.29.intmain()30.{31.charoutbuf[512];32.char*myname="tishion";33.lang_tlangtype=english;34.intfd=open("/dev/hello",O_RDWR,S_IRUSR|S_IWUSR);35.if(fd!=-1)36.{37.write(fd,myname,strlen(myname)+1);38.langtype=chinese;39.ioctl(fd,HELLO_IOCTL_SETLANG,&langtype);40.read(fd,outbuf,512);41.printf("langtype=chinese:%s/n",outbuf);42.memset(outbuf,0,512);43.langtype=pinyin;44.ioctl(fd,HELLO_IOCTL_SETLANG,&langtype);45.read(fd,outbuf,512);46.printf("langtype=pinyin:%s/n",outbuf);47.memset(outbuf,0,512);48.ioctl(fd,HELLO_IOCTL_RESETLANG,&langtype);49.read(fd,outbuf,512);50.printf("langtype=english:%s/n",outbuf);51.}52.else53.{54.perror("Failedatopen():");55.}56.}return0;編譯和運行過程圖[shion@shion-Ubuntu:?/projects/cpro/kernelpro/hello__mocl]$Ishello_mod.chello_mod_ioctl.hMakefilereadme.txt[shion@shion-Ubuntu:^/projects/cpro/kernelpro/hello_mod]$makemake-C/usr/src/linux-headers-2.6.35-25-genericM=/hon}e/shion/projects/cpra/kernelpro/hello_modmodulesmake[l]:Enteringdirectory'/usr/src/linux-headers-2.6.35-25-generic'CC[M]/home/shion/projects/cpro/kernelpro/hello^od/hello^od.oBuildingmodulesjstage2.WDPOST1modulesCC/home/shion/projects/cpro/kernelpro/hello_riiocl/hello_mod.raiod.oLD[M]/honte/shion/projects/cpro/kernelpro/hello^od/hello^ocl.komakefl]:Leavingdirectory'/usr/src/linux-headers-2.6.35-25-generic'[shion@shion-Ubuntu:^/projects/cpro/kernelpro/hello_niod]$sudoinsmodhello_(nod.ko[sudo]passwordforshion:[shion@shion-Ubuntu:^/projects/cpro/kernelpro/hello_mod]$cdtest/[shion@shion-Ubuntu:~/prejects/cpro/kernelpro/hello_mod/test]$Ishello_mod_test.c[shion@shion-Ubuntu:-/projects/cpro/kernelpro/hello_Riod/test]$gcchello_mod_test.c-□hello_mod_test.o[shion@shion-Ubuntu:^/projects/cpro/kernelpro/hello^od/test]$sudo./hello_mod_test.olangtype=chinese:f爾好!tishlon.langtype=pinyin:nihao!tishlon.langtype=english:Hello!tishlon.[shion@shion-Ubuntu:~/projects/cpro/kernelpro/hello__ffloci/test]$sudormmodhello__mod[shion@shion-Ubuntu:^/projects/cpro/ke:rnelpro/hello_mod/test]$[shion@shion-Ubuntu:~]$tail-40/var/log/messagesJun2112:32:30shion-Ubuntukernel:9770.141282;+hello_mod_init()!Dun2112:32:30shion-Ubuntukernel:9770.141680-hello_mod_init()!Jun2112:33:11shion-Ubuntukernel:9810.462966|+hello_mod_open()!Dun2112:33:11shion-Ubuntukernel::9810.465136|-hello_mod_open()!Jun2112:33:11shion-Ubuntukernel:9810.465189;|+hello_mod_v?/rite()!Dun2112:33:11shion-Ubuntukernel:9810.465351-hello_mod_write()!3un2112:33:11shion-Ubuntukernel:9810.465449+hello_mod_ioctl()!Jun2112:33:11shion-Ubuntukernel::9810.465460+switch()Jun2112:33:11shion-Ubuntukernel:9810.465477:>incase:HELLO3un2112:33:11shion-Ubuntukernel:9810.465520-switch()Jun2112:33:11shion-Ubuntukernel:9810.465530|-hello_mod_ioctl()!Dun2112:33:11shion-Ubuntukernel::9810.465587+hello_mod_read()!Jun2112:33:11shion-Ubuntukernel:9810.465662+sv/itch()Dun2112:33:11shion-Ubuntukernel:9810.465683>incase:chineJun2112:33:11shion-Ubuntukernel:9810.465713-switch()Dun2112:33:11shion-Ubuntukernel::9810.465785;-hello_mod_read
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 個人保險理賠授權委托書
- 單次包車合同范本
- 口罩委托采購合同范本
- 獸藥代理合同范本
- 世界水日活動策劃方案
- 下學期幼兒教師的個人總結
- 推拿治療學模擬題+答案
- 別墅建設合同范本
- 勞務合同補充合同范本
- 發(fā)光字安裝合同范本
- 火鍋店運營管理的問題與解決方案
- 【正版授權】 ISO 724:2023 EN ISO general purpose metric screw threads - Basic dimensions
- CJJ2-2008城市橋梁工程施工與質量驗收規(guī)范
- 新媒體營銷:營銷方式+推廣技巧+案例實訓 微課版 第2版 教學大綱
- 基于街區(qū)尺度的精細化大氣污染溯源模型建設需求
- 德育教育研究課題申報書
- 2024年岳陽職業(yè)技術學院單招職業(yè)適應性測試題庫匯編
- (高清版)JTG 3810-2017 公路工程建設項目造價文件管理導則
- 《ISO31000:2024風險管理指南》指導手冊(雷澤佳譯2024-04)
- 2024年甘肅省公務員公共基礎知識重點考試題庫(含答案)
- 《拒絕校園欺凌 防霸凌主題班會》課件
評論
0/150
提交評論