版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
上章回顧Linux設備驅動的簡介,以及分類字符設備塊設備網絡接口模塊的應用如何編寫模塊模塊相關的宏模塊和應用程序的區(qū)別編譯和裝載內核模塊字符設備驅動程序第2章預習檢查本章目標掌握字符設備驅動程序的基本結構和開發(fā)方法掌握用戶空間調用設備驅動程序的方法本章結構字符設備驅動基本結構
字符設備驅動程序
用戶空間調用設備驅動程序
添加驅動程序到內核
內核配置和編譯方法添加驅動程序到內核中主要概念和結構體實例字符驅動的主要組成2-1字符設備驅動程序基本結構字符設備開發(fā)的基本步驟確定主設備號和次設備號實現(xiàn)字符驅動程序實現(xiàn)file_operations結構體實現(xiàn)初始化函數,注冊字符設備實現(xiàn)銷毀函數,釋放字符設備創(chuàng)建設備文件節(jié)點2-1字符設備驅動程序基本結構什么是主設備號/次設備號主設備號是內核識別一個設備的標識。整數(占12bits),范圍從0到4095,通常使用1到255次設備號由內核使用,用于正確確定設備文件所指的設備。整數(占20bits),范圍從0到1048575,一般使用0到2552-1字符設備驅動程序基本結構設備編號的內部表達dev_t類型(32位):用來保存設備編號(包括主設備號(12位)和次設備號(20位))從dev_t獲得主設備號和次設備號:MAJOR(dev_t);MINOR(dev_t);將主設備號和次設備號轉換成dev_t類型:MKDEV(intmajor,intminor);
2-1字符設備驅動程序基本結構分配主設備號手工分配主設備號:找一個內核沒有使用的主設備號來使用。#include<linux/fs.h>int
register_chrdev_region(dev_tfirst,unsignedintcount,char*name);要分配的設備編號范圍的起始值,次設備號經常為0所請求的連續(xù)設備編號的個數和該編號范圍關聯(lián)的設備名稱2-1字符設備驅動程序基本結構動態(tài)分配主設備號:#include<linux/fs.h>intalloc_chrdev_resion(dev_t*dev,unsignedintfirstminor,unsignedintcount,char*name);輸出的設備號要使用的被請求的第一個次設備號2-1字符設備驅動程序基本結構釋放設備號void
unregister_chrdev_region(dev_tfirst,unsignedintcount);通常在模塊的清除函數中調用。2-1字符設備驅動程序基本結構實現(xiàn)字符驅動程序cdev結構體structcdev{ structkobjectkobj;/*內嵌的kobject對象*/ structmodule*owner;/*所屬模塊*/ structfile_operations*ops;/*文件操作結構體*/ structlist_headlist; dev_tdev;/*設備號*/ unsignedintcount;};2-1字符設備驅動程序基本結構操作cdev的函數voidcdev_init(structcdev*,structfile_operations*);structcdev*cdev_alloc(void);intcdev_add(structcdev*,dev_t,unsigned);voidcdev_del(structcdev*);用于初始化cdev的成員,并建立cdev和file_operations之間的連接分別向系統(tǒng)刪除一個cdev,完成字符設備的注銷,通常在模塊的卸載函數中調用分別向系統(tǒng)添加一個cdev,完成字符設備的注冊,通常在模塊加載函數中調用函數用于動態(tài)申請一個cdev內存2-1字符設備驅動程序基本結構file_operations結構體字符驅動和內核的接口:在include/linux/fs.h定義字符驅動只要實現(xiàn)一個file_operations結構體并注冊到內核中,內核就有了操作此設備的能力。2-1字符設備驅動程序基本結構
file_operations的主要成員:structmodule*owner:
指向模塊自身open:打開設備release:關閉設備read:從設備上讀數據write:向設備上寫數據ioctl:I/O控制函數llseek:定位讀寫指針mmap:映射設備空間到進程的地址空間2-1字符設備驅動程序基本結構file結構體
file結構:file_operations結構相關的一個結構體。描述一個正在打開的設備文件。成員:loff_tf_pos:
當前讀/寫位置unsignedintf_flags標識文件打開時,是否可讀或可寫O_RDONLYO_NONBLOCKO_SYNCstructfile_operations*f_op文件相關的操作,指向所實現(xiàn)的structfile_operationsvoid*private_data:
私有數據指針。驅動程序可以將這個字段用于任何目的或者忽略這個字段。2-1字符設備驅動程序基本結構inode結構體內核用inode結構在內部表示文件Inode與file的區(qū)別file表示打開的文件描述符多個表示打開的文件描述符的file結構,可以指向單個inode結構。2-1字符設備驅動程序基本結構Inode結構中的兩個主要字段:dev_ti_rdev;對表示設備文件的inode結構,該字段包含了真正的設備編號。structcdev*i_cdev;structcdev是表示字符設備的內核的內部結構。當inode指向一個字符設備文件時,該字段包含了指向structcdev結構的指針從一個inode中獲得主設備號和次設備號:unsignedintiminor(structinode*inode);unsignedintimajor(structinode*inode);2-1字符設備驅動程序基本結構注冊設備
,在模塊或驅動初始化時調用Linux-2.4及之前Linux-2.6intregister_chrdev(unsignedintmajor,constchar*name, structfile_operations*fops)如何操作字符設備的接口voidcdev_init(structcdev*,structfile_operations*);intcdev_add(structcdev*,dev_t,unsigned);2-1字符設備驅動程序基本結構注銷設備:在模塊卸載時調用Linux-2.4及之前Linux-2.6intunregister_chrdev(unsignedintmajor, constchar*name);voidcdev_del(structcdev*);2-1字符設備驅動程序基本結構//設備驅動模塊加載函數staticint__initxxx_init(void){ ... cdev_init(&xxx_dev.cdev,&xxx_fops);//初始化cdev xxx_dev.cdev.owner=THIS_MODULE; //獲取字符設備號 if(xxx_major) { register_chrdev_region(xxx_dev_no,1,DEV_NAME); } else { alloc_chrdev_region(&xxx_dev_no,0,1,DEV_NAME); } ret=cdev_add(&xxx_dev.cdev,xxx_dev_no,1);//注冊設備 ...}2-1字符設備驅動程序基本結構/*設備驅動模塊卸載函數*/staticvoid__exitxxx_exit(void){ unregister_chrdev_region(xxx_dev_no,1);//釋放占用的設備號
cdev_del(&xxx_dev.cdev);//注銷設備 ...}2-1字符設備驅動程序基本結構打開模塊使用計數加1識別次設備號硬件操作:檢查設備相關錯誤(諸如設備未就緒或類似的硬件問題);如果設備是首次打開,則對其初始化;如果有中斷操作,申請中斷處理程序;intopen(structinode*inode,structfile*filp);2-1字符設備驅動程序基本結構關閉模塊使用計數減1釋放由open分配的,保存在filp>private_data里的所有內容。硬件操作:如果申請了中斷,則釋放中斷處理程序。在最后一次關閉操作時關閉設備。intrelease(structinode*inode,structfile*filp);2-1字符設備驅動程序基本結構
read/writessize_tread(structfile*filp,char__user*buff,size_tcount,loff_t*offp);ssize_twrite(structfile*filp,constchar__user*buff,size_tcount,loff_t*offp);指向用戶空間的緩沖區(qū),這個緩沖區(qū)或者保存將寫入的數據,或者是一個存放新讀入數據的空緩沖區(qū)。用戶在文件中存取操作的位置2-1字符設備驅動程序基本結構
用戶空間和內核空間之間的數據拷貝過程,不能簡單的用指針操作或者memcpy來進行數據拷貝用戶空間的數據是可以被換出的,會產生一個頁面失效異常。用戶空間的地址無法在內核空間中使用。用戶空間和內核空間之間進行數據拷貝的函數:如果要復制的內存是簡單類型,如char、int、long等,put_user()和get_user()unsignedlongcopy_from_user(void*to,constvoid__user*from,unsignedlongcount);unsignedlongcopy_to_user(void__user*to,constvoid*from,unsignedlongcount);2-1字符設備驅動程序基本結構讀設備模板ssize_txxx_read(structfile*filp,char__user*buf, size_tcount,loff_t*f_pos){ ... copy_to_user(buf,...,...); ...}寫設備模板ssize_txxx_write(structfile*filp,constchar__user*buf, size_tcount,loff_t*f_pos){ ... copy_from_user(...,buf,...); ...}2-1字符設備驅動程序基本結構
ioctl函數為設備驅動程序執(zhí)行“命令”提供了一個特有的入口點用來設置或者讀取設備的屬性信息。intioctl(structinode*inode,structfile*filp, unsignedintcmd,unsignedlongarg);事先定義的IO控制命令
代碼arg為對應于cmd命令的參數2-1字符設備驅動程序基本結構cmd參數的定義不推薦用0x1,0x2,0x3之類的值Linux對ioctl()的cmd參數有特殊的定義構造命令編號的宏:_IO(type,nr)用于構造無參數的命令編號;_IOR(type,nr,datatype)用于構造從驅動程序中讀取數據的命令編號;_IOW(type,nr,datatype)用于寫入數據的命令;_IOWR(type,nr,datatype)用于雙向傳輸。type和number位字段通過參數傳入,而size位字段通過對datatype參數取sizeof獲得。
設備類型(type)
序列號(number)方向(direction)
數據尺寸(size)
8bit
8bit
2bit13/14bit2-1字符設備驅動程序基本結構Ioctl函數模板intxxx_ioctl(structinode*inode,structfile*filp,unsignedintcmd,unsignedlongarg){ ... switch(cmd) { caseXXX_CMD1: ... break; caseXXX_CMD2: ... break; default:///*不能支持的命令*/ return-ENOTTY; } return0;}階段總結本節(jié)介紹了字符設備驅動結構2-2添加驅動程序到內核配置內核編譯內核添加驅動程序到內核中2-2添加驅動程序到內核配置內核配置命令包括: makeconfig makemenuconfig makexconfig makegconfig
可通過“上”、“下”、“左”、“右”鍵移動菜單,選擇某項按“Y”,取消選擇按“N”,如果選擇某項編譯為模塊按“M”,進入子菜單按“Enter”,返回上一級菜單按“Esc”使用makeconfig、makemenuconfig等命令后,會生成一個.config配置文件(是隱身文件,通過ls–a才能看到)
2-2添加驅動程序到內核編譯內核可用如下命令編譯內核:makeARC=armCROSS_COMPILE=arm-linux-zImage源代碼根目錄的Makefile中將ARCH和CROSS_COMPILE直接指定為arm和arm-linux-,如:
這樣就沒有必要每次編譯的時候都指定體系結構和交叉編譯器了,只須使用下面命令就可以了:
makezImageARCH ?=armCROSS_COMPILE ?=arm-linux-2-2添加驅動程序到內核添加驅動程序到內核Linux2.6內核的配置系統(tǒng)由以下3個部分組成。Makefile:分布在Linux內核源代碼中的Makefite定義Linux內核的編譯規(guī)則配置文件(Kconfig):給用戶提供配置選擇的功能。配置工具:包括配置命令解釋器(對配置腳本中使用的配置命令進行解釋)配置用戶界面(提供字符界面和圖形界面)。這些配置工具都是使用腳本語言編寫的,如Tcl/TK、Perl等。在Linux內核中增加程序需要完成以下3項工作。將編寫的源代碼復制到Linux內核源代碼的相應目錄。在目錄的Kconfig文件中增加新源代碼對應項目的編譯配置選項。在目錄的Makefile文件中增加對新源代碼的編譯條目。2-2添加驅動程序到內核實例:在內核源代碼drivers目錄下為ARM體系結構新增testdrivertestdriver的樹形目錄:步驟:
1、拷貝test到drivers路徑下 2、為新增目錄創(chuàng)建Kconfig和Makefile 3、修改新增目錄父目錄的Kconfig和 Makefile,以便新增的Kconfig和 Makefile能夠被引用 4、在arch/arm/Kconfig里增加 source“drivers/test/Kconfig”2-2添加驅動程序到內核步驟:1、拷貝test到drivers路徑下cp–frtestlinux_kernel_path/drivers2、為新增目錄創(chuàng)建Kconfig和Makefile
2-2添加驅動程序到內核修改新增目錄的父目錄的Kconfig和Makefile在drivers/Kconig中加入:source"drivers/test/Kconfig“在drivers/Makefile中加入:obj-$(CONFIG_TEST)+=
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 地契合同合同協(xié)議書
- 散裝水泥買賣合同協(xié)議
- 2025年公寓房屋買賣合同
- 2025年醫(yī)療器械過程驗證合同
- 2025年多渠道策略技術咨詢服務合同
- 金融投資合同
- 產品銷售合作合同范本模板
- 2025年度個人與公司專利居間許可合同3篇
- 2025版外銷合同范本:新能源產品海外銷售合作協(xié)議5篇
- 2025版施工電梯安裝與安全防護設施配套合同3篇
- 數學-山東省2025年1月濟南市高三期末學習質量檢測濟南期末試題和答案
- 中儲糧黑龍江分公司社招2025年學習資料
- 2024-2025學年人教版三年級(上)英語寒假作業(yè)(九)
- 河南退役軍人專升本計算機真題答案
- 湖南省長沙市2024-2025學年高一數學上學期期末考試試卷
- 船舶行業(yè)維修保養(yǎng)合同
- 駕駛證學法減分(學法免分)試題和答案(50題完整版)1650
- 2024年林地使用權轉讓協(xié)議書
- 物流有限公司安全生產專項整治三年行動實施方案全國安全生產專項整治三年行動計劃
- 2025屆江蘇省13市高三最后一卷生物試卷含解析
- 2023年漢中市人民政府國有資產監(jiān)督管理委員會公務員考試《行政職業(yè)能力測驗》歷年真題及詳解
評論
0/150
提交評論