LINUX設(shè)備驅(qū)動開發(fā)及內(nèi)核原理課件_第1頁
LINUX設(shè)備驅(qū)動開發(fā)及內(nèi)核原理課件_第2頁
LINUX設(shè)備驅(qū)動開發(fā)及內(nèi)核原理課件_第3頁
LINUX設(shè)備驅(qū)動開發(fā)及內(nèi)核原理課件_第4頁
LINUX設(shè)備驅(qū)動開發(fā)及內(nèi)核原理課件_第5頁
已閱讀5頁,還剩90頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

嵌入式Linux驅(qū)動高級開發(fā)及內(nèi)核原理

日程安排設(shè)備驅(qū)動簡介建立和運(yùn)行模塊字符驅(qū)動調(diào)試技術(shù)并發(fā)和競爭高級字符驅(qū)動操作時(shí)間,延時(shí)和延后工作分配內(nèi)存與硬件通訊中斷處理塊設(shè)備驅(qū)動日程安排設(shè)備驅(qū)動簡介Kernel的作用Kernel可劃分為下列功能單元進(jìn)程管理:進(jìn)程調(diào)度,資源分配,進(jìn)程間通信.內(nèi)存管理:其實(shí)也算是資源分配的一部分文件系統(tǒng):管理,組織物理媒介上數(shù)據(jù)的方法設(shè)備控制:設(shè)備驅(qū)動(ldd3所關(guān)注的)網(wǎng)絡(luò):實(shí)質(zhì)上是進(jìn)程間通信.但它不局限于一個(gè)特定的進(jìn)程.它關(guān)注收/發(fā)packets,路由,地址解析...

Kernel的結(jié)構(gòu)模塊可加載模塊(lodablemodules)module:可實(shí)時(shí)加載到內(nèi)核中的代碼,它可動態(tài)連接到內(nèi)核(insmod,rmmod)設(shè)備驅(qū)動就是module的代表,但module還包括文件系統(tǒng)等等.

字符設(shè)備和塊設(shè)備字符設(shè)備:以字節(jié)流的形式被訪問的設(shè)備。e.g:/dev/console:文本控制臺./dev/ttyS0:串口它通過文件系統(tǒng)節(jié)點(diǎn)被訪問.e.g:/dev/tty1,/dev/lp0字符設(shè)備與一般文件(regularfile)的區(qū)別可以在一般文件中前后移動(lseek),但只能順序訪問字符設(shè)備.當(dāng)然,也有特例:framegrabbers.塊設(shè)備:能支持文件系統(tǒng)的設(shè)備傳統(tǒng)的UNIX:只能以block(512B)為單位訪問塊設(shè)備 Linux:能以訪問字符設(shè)備的方式訪問塊設(shè)備,即以字節(jié)文單位訪問塊設(shè)備.Linux中字符設(shè)備與塊設(shè)備的區(qū)別內(nèi)核內(nèi)部對數(shù)據(jù)的組織和管理不同,對驅(qū)動開發(fā)者來說透明接口不同:使用兩套不同的interface網(wǎng)絡(luò)設(shè)備網(wǎng)絡(luò)接口:能與其他主機(jī)通信的設(shè)備它可以是硬件設(shè)備,也可以是軟件設(shè)備,比如lo.(參考TCP/IP詳解p26)網(wǎng)絡(luò)接口只管收發(fā)數(shù)據(jù)包,而不管這些數(shù)據(jù)包被什么協(xié)議所使用不同于字符設(shè)備和塊設(shè)備,網(wǎng)絡(luò)接口沒有對應(yīng)的文件系統(tǒng)節(jié)點(diǎn).雖然可以通過類似eth0這樣的"文件名"來訪問網(wǎng)絡(luò)接口,但文件系統(tǒng)節(jié)點(diǎn)中卻沒有針對網(wǎng)絡(luò)接口的節(jié)點(diǎn)內(nèi)核與網(wǎng)絡(luò)接口之間的通信也不同于內(nèi)核與字符/塊設(shè)備之間的通信(read,write),它們之間使用特定的傳輸數(shù)據(jù)包的函數(shù)調(diào)用其他設(shè)備也有一些module不能嚴(yán)格地劃分類型.USBmodule:它工作在內(nèi)核的USB子系統(tǒng)之上實(shí)際的USB設(shè)備可以是字符設(shè)備,塊設(shè)備,也可以是網(wǎng)絡(luò)接口在設(shè)備驅(qū)動之外,別的功能,不論硬件和軟件,在內(nèi)核中都是模塊化的例如文件系統(tǒng)建立和運(yùn)行模塊建立開發(fā)環(huán)境ldd3例子開發(fā)環(huán)境linux驅(qū)動開發(fā)需要預(yù)先安裝內(nèi)核源碼源碼需要從官方下載或者其他發(fā)行版的官方下載直接解壓到/usr/src目錄下版本影響內(nèi)核官方版本注意注意發(fā)行版的內(nèi)部版本最新內(nèi)核版本linux2.6.20/21工作隊(duì)列接口變化小版本變動不會對驅(qū)動的架構(gòu)造成太大影響對于不同發(fā)行版,不同內(nèi)核版本要做少量移植和測試內(nèi)核模塊VS應(yīng)用程序執(zhí)行機(jī)制不同模塊初始化模塊退出類似事件編程使用庫不一樣無法使用標(biāo)準(zhǔn)庫只能調(diào)用內(nèi)核提供的函數(shù)用戶空間VS內(nèi)核空間用戶空間VS內(nèi)核空間應(yīng)用程序運(yùn)行在用戶空間設(shè)備模塊運(yùn)行在內(nèi)核空間運(yùn)行模式不一樣內(nèi)存地址映射也不一樣用戶空間和內(nèi)核空間的轉(zhuǎn)換可能發(fā)生在進(jìn)程中的系統(tǒng)調(diào)用時(shí)或者硬件中斷系統(tǒng)調(diào)用雖然在內(nèi)核中執(zhí)行,但是依然是在進(jìn)程的上下文中進(jìn)行的,所以可以訪問到進(jìn)程中的數(shù)據(jù)。中斷處理和進(jìn)程是異步的了,而且不和任何進(jìn)程有關(guān)系模塊跨越兩個(gè)空間,有兩個(gè)觸發(fā)入口一些函數(shù)作為系統(tǒng)調(diào)用的一部分執(zhí)行一些函數(shù)負(fù)責(zé)中斷處理

模塊的加載卸載和查看加載使用insmod卸載使用rmmod查看使用lsmod模塊代碼staticint__initinitialization_function(void){

/*initializationcodehere*/}module_init(initialization_function);模塊代碼staticvoid__exitcleanup_function(void){

/*Cleanupcodehere*/}module_exit(cleanup_function);如何編寫清理函數(shù)void__exitmy_cleanup_function(void){unregister_those(ptr3,"skull");unregister_that(ptr2,"skull");unregister_this(ptr1,"skull");return;}日程安排設(shè)備驅(qū)動簡介建立和運(yùn)行模塊字符驅(qū)動主次設(shè)備號字符設(shè)備可以通過文件系統(tǒng)來存取字符設(shè)備一般位于/dev下有c標(biāo)志的是字符設(shè)備有b標(biāo)志的是塊設(shè)備設(shè)備號文檔Documentation/devices.txt主設(shè)備號決定驅(qū)動的種類次設(shè)備號決定使用哪個(gè)設(shè)備分配和釋放設(shè)備編號分配指定的主設(shè)備號intregister_chrdev_region(dev_tfirst,unsignedintcount,char*name);動態(tài)分配主設(shè)備號intalloc_chrdev_region(dev_t*dev,unsignedintfirstminor,unsignedintcount,char*name);釋放voidunregister_chrdev_region(dev_tfirst,unsignedintcount);字符驅(qū)動中重要的數(shù)據(jù)結(jié)構(gòu)

fileinodeRelease方法釋放由open分配的,保存在filp->private中的所有內(nèi)容在最后一次關(guān)閉操作時(shí)關(guān)閉設(shè)備日程安排設(shè)備驅(qū)動簡介建立和運(yùn)行模塊字符驅(qū)動調(diào)試技術(shù)通過打印調(diào)試通過宏可以定義日志級別參考P79如果開啟Klogd及Syslogd則輸出到日志日志文件參考/var/log/message在printk當(dāng)中打印設(shè)備編號Print_dev_tFormat_dev_t日程安排設(shè)備驅(qū)動簡介建立和運(yùn)行模塊字符驅(qū)動調(diào)試技術(shù)并發(fā)和競爭并發(fā)和管理并發(fā)源很多多個(gè)進(jìn)程運(yùn)行SMP多個(gè)CPU并行設(shè)備中斷延遲機(jī)制(工作隊(duì)列,定時(shí)器,Tasklet)并發(fā)和競爭兩個(gè)或多個(gè)進(jìn)程讀寫某些共享數(shù)據(jù),而最后的結(jié)果取決于進(jìn)程運(yùn)行的精確時(shí)序,就稱為競爭條件(RaceConditions)。競爭情況來自對資源的共享存取的結(jié)果.存取管理的常用技術(shù)是加鎖或者互斥其次常用的技術(shù)是引用計(jì)數(shù)臨界區(qū)把對共享內(nèi)存進(jìn)行訪問的程序片段稱作臨界區(qū)(criticalregion),或臨界段(criticalsection)。如果我們能夠適當(dāng)?shù)匕才攀沟脙蓚€(gè)進(jìn)程不可能同時(shí)處于臨界區(qū),則就能夠避免競爭條件。臨界區(qū)四要素任何兩個(gè)進(jìn)程不能同時(shí)處于臨界區(qū)臨界區(qū)外的進(jìn)程不能阻塞其他進(jìn)程不能使進(jìn)程在臨界區(qū)外無限等待不應(yīng)對CPU的速度和數(shù)目做假設(shè)PV操作解決同步互斥PV原語的含義

P操作和V操作是不可中斷的程序段,稱為原語。PV原語及信號量的概念都是由荷蘭科學(xué)家E.W.Dijkstra提出的。信號量sem是一整數(shù),sem大于等于零時(shí)代表可供并發(fā)進(jìn)程使用的資源實(shí)體數(shù),但sem小于零時(shí)則表示正在等待使用臨界區(qū)的進(jìn)程數(shù)。

P原語操作的動作是:

(1)sem減1;

(2)若sem減1后仍大于或等于零,則進(jìn)程繼續(xù)執(zhí)行;

(3)若sem減1后小于零,則該進(jìn)程被阻塞后進(jìn)入與該信號相對應(yīng)的隊(duì)列中,然后轉(zhuǎn)進(jìn)程調(diào)度。

V原語操作的動作是:

(1)sem加1;

(2)若相加結(jié)果大于零,則進(jìn)程繼續(xù)執(zhí)行;

(3)若相加結(jié)果小于或等于零,則從該信號的等待隊(duì)列中喚醒一等待進(jìn)程,然后再返回原進(jìn)程繼續(xù)執(zhí)行或轉(zhuǎn)進(jìn)程調(diào)度。

PV操作對于每一個(gè)進(jìn)程來說,都只能進(jìn)行一次,而且必須成對使用。在PV原語執(zhí)行期間不允許有中斷的發(fā)生。

解決互斥用PV原語實(shí)現(xiàn)進(jìn)程的互斥由于用于互斥的信號量sem與所有的并發(fā)進(jìn)程有關(guān),所以稱之為公有信號量。公有信號量的值反映了公有資源的數(shù)量。只要把臨界區(qū)置于P(sem)和V(sem)之間,即可實(shí)現(xiàn)進(jìn)程間的互斥。就象火車中的每節(jié)車廂只有一個(gè)衛(wèi)生間,該車廂的所有旅客共享這個(gè)公有資源:衛(wèi)生間,所以旅客間必須互斥進(jìn)入衛(wèi)生間,只要把衛(wèi)生間放在P(sem)和V(sem)之間,就可以到達(dá)互斥的效果。

解決同步用PV原語實(shí)現(xiàn)進(jìn)程的同步與進(jìn)程互斥不同,進(jìn)程同步時(shí)的信號量只與制約進(jìn)程及被制約進(jìn)程有關(guān)而不是與整組并發(fā)進(jìn)程有關(guān),所以稱該信號量為私有信號量。利用PV原語實(shí)現(xiàn)進(jìn)程同步的方法是:首先判斷進(jìn)程間的關(guān)系為同步的,且為各并發(fā)進(jìn)程設(shè)置私有信號量,然后為私有信號量賦初值,最后利用PV原語和私有信號量規(guī)定各進(jìn)程的執(zhí)行順序。Linux信號量實(shí)現(xiàn)voidsema_init(structsemaphore*sem,intval);DECLARE_MUTEX(name);DECLARE_MUTEX_LOCKED(name);voidinit_MUTEX(structsemaphore*sem);voidinit_MUTEX_LOCKED(structsemaphore*sem);voiddown(structsemaphore*sem);intdown_interruptible(structsemaphore*sem);intdown_trylock(structsemaphore*sem);voidup(structsemaphore*sem);日程安排設(shè)備驅(qū)動簡介建立和運(yùn)行模塊字符驅(qū)動調(diào)試技術(shù)并發(fā)和競爭高級字符驅(qū)動操作ioctl接口大部分驅(qū)動需要通過設(shè)備驅(qū)動進(jìn)行各種硬件控制的能力.大部分設(shè)備可進(jìn)行超出簡單的數(shù)據(jù)傳輸之外的操作;例如,設(shè)備鎖上它的門,彈出它的介質(zhì),報(bào)告錯誤信息,改變波特率,或者自我銷毀.這些操作常常通過ioctl方法來支持,它通過相同名字的系統(tǒng)調(diào)用來實(shí)現(xiàn).阻塞I/O數(shù)據(jù)操作可能會遇到read的調(diào)用時(shí)可能沒有數(shù)據(jù)時(shí)Write的調(diào)用時(shí)設(shè)備沒有準(zhǔn)備好接受數(shù)據(jù)當(dāng)驅(qū)動不能立刻滿足要求怎么辦程序員希望調(diào)用read或write并且使調(diào)用返回驅(qū)動應(yīng)當(dāng)(缺省地)阻塞進(jìn)程,使它進(jìn)入睡眠直到請求可繼續(xù).進(jìn)程的休眠進(jìn)程被置為睡眠,從調(diào)度器的運(yùn)行隊(duì)列移除睡眠的進(jìn)程被擱置一邊,等待以后發(fā)生事件睡眠注意安全編程在原子上下文時(shí)不能睡眠休眠醒來,無法確定休眠時(shí)間和時(shí)序休眠的進(jìn)程必須有時(shí)機(jī)被喚醒與休眠相關(guān)的數(shù)據(jù)結(jié)構(gòu)和函數(shù)等待隊(duì)列等待-喚醒函數(shù)wait_event(queue,condition)wait_event_interruptible(queue,condition)wait_event_timeout(queue,condition,timeout)wait_event_interruptible_timeout(queue,condition,timeout)voidwake_up(wait_queue_head_t*queue);voidwake_up_interruptible(wait_queue_head_t*queue);阻塞操作的推薦用法阻塞操作標(biāo)準(zhǔn)語法:如果一個(gè)進(jìn)程調(diào)用read但是沒有數(shù)據(jù)可用(尚未),這個(gè)進(jìn)程必須阻塞.這個(gè)進(jìn)程在有數(shù)據(jù)達(dá)到時(shí)被立刻喚醒,并且那個(gè)數(shù)據(jù)被返回給調(diào)用者,即便小于在給方法的count參數(shù)中請求的數(shù)量.如果一個(gè)進(jìn)程調(diào)用write并且在緩沖中沒有空間,這個(gè)進(jìn)程必須阻塞,并且它必須在一個(gè)與用作read的不同的等待隊(duì)列中.當(dāng)一些數(shù)據(jù)被寫入硬件設(shè)備,并且在輸出緩沖中的空間變空閑,這個(gè)進(jìn)程被喚醒并且寫調(diào)用成功,盡管數(shù)據(jù)可能只被部分寫入,這時(shí)緩沖內(nèi)沒有足夠空間給被請求的count字節(jié).非阻塞I/O,poll和select可以實(shí)現(xiàn)非阻塞讀寫多個(gè)文件三者的區(qū)別和聯(lián)系select在BSDUnix中引入poll是SystemV的解決方案epoll擴(kuò)展到幾千個(gè)文件描述符,提高了性能內(nèi)部實(shí)現(xiàn)unsignedint(*poll)(structfile*filp,poll_table*wait);日程安排設(shè)備驅(qū)動簡介建立和運(yùn)行模塊字符驅(qū)動調(diào)試技術(shù)并發(fā)和競爭高級字符驅(qū)動操作時(shí)間,延時(shí)和延后工作測量時(shí)間流失內(nèi)核通過定時(shí)器中斷來跟蹤時(shí)間的流動定時(shí)器中斷由系統(tǒng)定時(shí)硬件以規(guī)律地間隔產(chǎn)生每次發(fā)生一個(gè)時(shí)鐘中斷,一個(gè)內(nèi)核計(jì)數(shù)器的值遞增.這個(gè)計(jì)數(shù)器在系統(tǒng)啟動時(shí)初始化為0,因此它代表從最后一次啟動以來的時(shí)鐘嘀噠的數(shù)目這個(gè)計(jì)數(shù)器是一個(gè)64-位變量(即便在32-位的體系上)并且稱為jiffies_64獲知當(dāng)前時(shí)間voiddo_gettimeofday(structtimeval*tv);延后執(zhí)行長延時(shí)技術(shù)忙等待讓出處理器超時(shí)短延時(shí)技術(shù)voidndelay(unsignedlongnsecs);voidudelay(unsignedlongusecs);voidmdelay(unsignedlongmsecs);

內(nèi)核定時(shí)器structtimer_list{/*...*/unsignedlongexpires;void(*function)(unsignedlong);unsignedlongdata;};voidinit_timer(structtimer_list*timer);structtimer_listTIMER_INITIALIZER(_function,_expires,_data);voidadd_timer(structtimer_list*timer);intdel_timer(structtimer_list*timer);Tasklets機(jī)制structtasklet_struct{/*...*/void(*func)(unsignedlong);unsignedlongdata;};voidtasklet_init(structtasklet_struct*t,void(*func)(unsignedlong),unsignedlongdata);DECLARE_TASKLET(name,func,data);DECLARE_TASKLET_DISABLED(name,func,data);Tasklet特性一個(gè)tasklet能夠被禁止并且之后被重新使能;它不會執(zhí)行直到它被使能與被禁止相同的的次數(shù).如同定時(shí)器,一個(gè)tasklet可以注冊它自己.一個(gè)tasklet能被調(diào)度來執(zhí)行以正常的優(yōu)先級或者高優(yōu)先級.后一組一直是首先執(zhí)行.taslet可能立刻運(yùn)行,如果系統(tǒng)不在重載下,但是從不會晚于下一個(gè)時(shí)鐘嘀噠.一個(gè)tasklet可能和其他tasklet并發(fā),但是對它自己是嚴(yán)格地串行的--同樣的tasklet從不同時(shí)運(yùn)行在超過一個(gè)處理器上.同樣,如已經(jīng)提到的,一個(gè)tasklet常常在調(diào)度它的同一個(gè)CPU上運(yùn)行.工作隊(duì)列工作隊(duì)列表面類似于tasketstasklet在軟件中斷上下文中運(yùn)行的結(jié)果是所有的tasklet代碼必須是原子的.相反,工作隊(duì)列函數(shù)在一個(gè)特殊內(nèi)核進(jìn)程上下文運(yùn)行;結(jié)果,它們有更多的靈活性.特別地,工作隊(duì)列函數(shù)能夠睡眠.tasklet常常在它們最初被提交的處理器上運(yùn)行.工作隊(duì)列以相同地方式工作內(nèi)核代碼可以請求工作隊(duì)列函數(shù)被延后一個(gè)明確的時(shí)間間隔.工作隊(duì)列structworkqueue_struct*create_workqueue(constchar*name);structworkqueue_struct*create_singlethread_workqueue(constchar*name);

日程安排設(shè)備驅(qū)動簡介建立和運(yùn)行模塊字符驅(qū)動調(diào)試技術(shù)并發(fā)和競爭高級字符驅(qū)動操作時(shí)間,延時(shí)和延后工作分配內(nèi)存內(nèi)存分配內(nèi)存分配的最常用接口.#include<linux/slab.h>void*kmalloc(size_tsize,intflags);voidkfree(void*obj);內(nèi)存分配標(biāo)志控制內(nèi)存分配如何進(jìn)行的標(biāo)志,從最少限制的到最多的.GFP_USER和GFP_KERNEL優(yōu)先級允許當(dāng)前進(jìn)程被置為睡眠來滿足請求.GFP_NOFS和GFP_NOIO禁止文件系統(tǒng)操作和所有的I/O操作,分別地,而GFP_ATOMIC分配根本不能睡眠.#include<linux/mm.h>GFP_USERGFP_KERNELGFP_NOFSGFP_NOIOGFP_ATOMIC內(nèi)存分配標(biāo)志這些標(biāo)志分配內(nèi)存時(shí)修改內(nèi)核的行為__GFP_DMA__GFP_HIGHMEM__GFP_COLD__GFP_NOWARN__GFP_HIGH__GFP_REPEAT__GFP_NOFAIL__GFP_NORETRYslab緩存創(chuàng)建和銷毀一個(gè)slab緩存.這個(gè)緩存可被用來分配幾個(gè)相同大小的對象.#include<linux/malloc.h>kmem_cache_t*kmem_cache_create(char*name,size_tsize,size_toffset,unsignedlongflags,constructor(),destructor());intkmem_cache_destroy(kmem_cache_t*cache);緩存標(biāo)志在創(chuàng)建一個(gè)緩存時(shí)可指定的標(biāo)志.SLAB_CTOR_ATOMICSLAB_CTOR_CONSTRUCTOR緩存中分配釋放單個(gè)對象從緩存中分配和釋放一個(gè)單個(gè)對象./proc/slabinfo一個(gè)包含對slab緩存使用情況統(tǒng)計(jì)的虛擬文件.void*kmem_cache_alloc(kmem_cache_t*cache,intflags);voidkmem_cache_free(kmem_cache_t*cache,constvoid*obj);日程安排設(shè)備驅(qū)動簡介建立和運(yùn)行模塊字符驅(qū)動調(diào)試技術(shù)并發(fā)和競爭高級字符驅(qū)動操作時(shí)間,延時(shí)和延后工作分配內(nèi)存I/O讀寫硬件讀寫屏障硬件內(nèi)存屏障.它們請求CPU(和編譯器)來檢查所有的跨這個(gè)指令的內(nèi)存讀,寫#include<asm/system.h>voidrmb(void);voidread_barrier_depends(void);voidwmb(void);voidmb(void);I/O讀寫用來讀和寫I/O端口的函數(shù).它們還可以被用戶空間程序調(diào)用,如果它們有正當(dāng)?shù)臋?quán)限來存取端口.#include<asm/io.h>unsignedinb(unsignedport);voidoutb(unsignedcharbyte,unsignedport);unsignedinw(unsignedport);voidoutw(unsignedshortword,unsignedport);unsignedinl(unsignedport);voidoutl(unsigneddoubleword,unsignedport);延時(shí)讀寫函數(shù)如果在一次I/O操作后需要一個(gè)小延時(shí),你可以使用在前一項(xiàng)中介紹的這些函數(shù)的6個(gè)暫停對應(yīng)部分;這些暫停函數(shù)以_p結(jié)尾unsignedinb_p(unsignedport);字串函數(shù)這些"字串函數(shù)"被優(yōu)化為傳送數(shù)據(jù)從一個(gè)輸入端口到一個(gè)內(nèi)存區(qū),或者其他的方式.這些傳送通過讀或?qū)懙酵欢丝赾ount次來完成.voidinsb(unsignedport,void*addr,unsignedlongcount);voidoutsb(unsignedport,void*addr,unsignedlongcount);voidinsw(unsignedport,void*addr,unsignedlongcount);voidoutsw(unsignedport,void*addr,unsignedlongcount);voidinsl(unsignedport,void*addr,unsignedlongcount);voidoutsl(unsignedport,void*addr,unsignedlongcount);I/O端口資源分配I/O端口的資源分配器.這個(gè)檢查函數(shù)成功返回0并且在錯誤時(shí)小于0#include<linux/ioport.h>structresource*request_region(unsignedlongstart,unsignedlonglen,char*name);voidrelease_region(unsignedlongstart,unsignedlonglen);intcheck_region(unsignedlongstart,unsignedlonglen);I/O地址映射ioremap重映射一個(gè)物理地址范圍到處理器的虛擬地址空間,使它對內(nèi)核可用.iounmap釋放映射當(dāng)不再需要它時(shí).#include<asm/io.h>void*ioremap(unsignedlongphys_addr,unsignedlongsize);void*ioremap_nocache(unsignedlongphys_addr,unsignedlongsize);voidiounmap(void*virt_addr);內(nèi)存區(qū)處理資源分配為內(nèi)存區(qū)處理資源分配的函數(shù)structresource*request_mem_region(unsignedlongstart,unsignedlonglen,char*name);voidrelease_mem_region(unsignedlongstart,unsignedlonglen);intcheck_mem_region(unsignedlongstart,unsignedlonglen);I/O內(nèi)存存取函數(shù)用來使用I/O內(nèi)存的存取者函數(shù).#include<asm/io.h>unsignedintioread8(void*addr);unsignedintioread16(void*addr);unsignedintioread32(void*addr);voidiowrite8(u8value,void*addr);voidiowrite16(u16value,void*addr);voidiowrite32(u32value,void*addr);

I/O內(nèi)存函數(shù).舊的,類型不安全的存取I/O內(nèi)存的函數(shù).unsignedreadb(address);unsignedreadw(address);unsignedreadl(address);voidwriteb(unsignedvalue,address);voidwritew(unsignedvalue,address);voidwritel(unsignedvalue,address);memset_io(address,value,count);memcpy_fromio(dest,source,nbytes);memcpy_toio(dest,source,nbytes);日程安排設(shè)備驅(qū)動簡介建立和運(yùn)行模塊字符驅(qū)動調(diào)試技術(shù)并發(fā)和競爭高級字符驅(qū)動操作時(shí)間,延時(shí)和延后工作分配內(nèi)存與硬件通訊中斷處理注冊注銷中斷處理調(diào)用這個(gè)注冊和注銷一個(gè)中斷處理.#include<linux/interrupt.h>intrequest_irq(unsignedintirq,irqreturn_t(*handler)(),unsignedlongflags,constchar*dev_name,void*dev_id);voidfree_irq(unsignedintirq,void*dev_id);中斷申請標(biāo)志給request_irq的標(biāo)志.SA_INTERRUPT請求安裝一個(gè)快速處理者(相反是一個(gè)慢速的).SA_SHIRQ安裝一個(gè)共享的處理者#include<asm/signal.h>SA_INTERRUPTSA_SHIRQSA_SAMPLE_RANDOM中斷的文件系統(tǒng)節(jié)點(diǎn)報(bào)告硬件中斷和安裝的處理者的文件系統(tǒng)節(jié)點(diǎn)./proc/interrupts/proc/stat驅(qū)動使用探測函數(shù)驅(qū)動使用的函數(shù),探測決定哪個(gè)中斷線被設(shè)備在使用.probe_irq_on的結(jié)果必須傳回給probe_irq_off在中斷產(chǎn)生之后.probe_irq_off的返回值是被探測的中斷號.unsignedlongprobe_irq_on(void);intprobe_irq_off(unsignedlong);中斷處理返回從一個(gè)中斷處理返回的可能值,指示是否一個(gè)來自設(shè)備的真正的中斷出現(xiàn)了.IRQ_NONEIRQ_HANDLEDIRQ_RETVAL(intx)使能和禁止中斷可以使能和禁止中斷。共享處理不使用這個(gè)函數(shù).voiddisable_irq(intirq);voiddisable_irq_nosync(intirq);voidenable_irq(intirq);禁止中斷使用local_irq_save來禁止本地處理器的中斷并且記住它們之前的狀態(tài)voidlocal_irq_save(unsignedlongflags);voidlocal_irq_restore(unsignedlongflags);使能和禁止中斷在當(dāng)前處理器無條件禁止和使能中斷的函數(shù).voidlocal_irq_disable(void);voidlocal_irq_enable(void);日程安排設(shè)備驅(qū)動簡介建立和運(yùn)行模塊字符驅(qū)動調(diào)試技術(shù)并發(fā)和競爭高級字符驅(qū)動操作時(shí)間,延時(shí)和延后工作分配內(nèi)存與硬件通訊中斷處理塊設(shè)備驅(qū)動塊設(shè)備注冊register_blkdev注冊一個(gè)塊驅(qū)動到內(nèi)核,并且,可選地,獲得一個(gè)主編號.一個(gè)驅(qū)動可被注銷,使用unregister_blkdev.#include<linux/fs.h>intregister_blkdev(unsignedintmajor,constchar*name);intunregister_blkdev(unsignedintmajor,constchar*name);塊設(shè)備相關(guān)數(shù)據(jù)結(jié)構(gòu)塊設(shè)備驅(qū)動的數(shù)據(jù)結(jié)構(gòu).structblock_device_operations描述內(nèi)核中單個(gè)塊設(shè)備的結(jié)構(gòu).#include<linux/genhd.h>structgendisk;分配gendisk結(jié)構(gòu)的函數(shù),并且返回它們到系統(tǒng).structgendisk*alloc_disk(intminors);voidadd_disk(structgendisk*gd); 塊設(shè)備相關(guān)函數(shù)voidset_capacity(structgendisk*gd,sector_tsectors);存儲設(shè)備能力(以512-字節(jié))在gendisk結(jié)構(gòu)中.voidadd_disk(structgendisk*gd);添加一個(gè)磁盤到內(nèi)核.一旦調(diào)用這個(gè)函數(shù),你的磁盤的方法可被內(nèi)核調(diào)用.intcheck_disk_change(structblock_device*bdev);一個(gè)內(nèi)核函數(shù),檢查在給定磁盤驅(qū)動器中的介質(zhì)改變,并且采取要求的清理動作當(dāng)檢測到這樣一個(gè)改變.請求隊(duì)列相關(guān)函數(shù)#include<linux/blkdev.h>request_queue_tblk_init_queue(request_fn_proc*request,spinlock_t*lock);voidblk_cleanup_queue(request_queue_t*);處理塊請求隊(duì)列的創(chuàng)建和刪除的函數(shù).structrequest*elv_next_request(request_queue_t*queue);voidend_request(structrequest*req,intsuccess);elv_next_request從一個(gè)請求隊(duì)列中獲得下一個(gè)請求;end_request可用在每個(gè)簡單驅(qū)動器中來標(biāo)識一個(gè)(或部分)請求完成.voidblkdev_dequeue_request(structrequest*req);voidelv_requeue_request(request_queue_t*queue,structrequest*req);從隊(duì)列中除去一個(gè)請求,并且放回它的函數(shù)如果需要.voidblk_stop_queue(request_queue_t*queue);voidblk_start_queue(request_queue_t*queue);如果你需要阻止對你的請求函數(shù)的進(jìn)一步調(diào)用,調(diào)用blk_stop_queue來完成.調(diào)用blk_start_queue來使你的請求方法被再次調(diào)用.請求隊(duì)列參數(shù)控制函數(shù)設(shè)置各種隊(duì)列參數(shù)的函數(shù),來控制請求如何被創(chuàng)建給一個(gè)特殊設(shè)備voidblk_queue_bounce_limit(request_queue_t*queue,u64dma_addr);voidblk_queue_max_sectors(request_queue_t*queue,unsignedshortmax);voidblk_queue_max_phys_segments(request_queue_t*queue,unsignedshortmax);voidblk_queue_max_hw_segments(request_queue_t*queue,unsignedshortmax);voidblk_queue_max_segment_size(request_queue_t*queue,unsignedintmax);blk_queue_segment_boundary(request_queue_t*queue,unsignedlongmask);voidblk_queue_dma_alignment(request_queue_t*queue,intmask);voidblk_queue_hardsect_size(request_queue_t*queue,unsignedshort

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論