第8章設(shè)備驅(qū)動(dòng)(初稿)_第1頁(yè)
第8章設(shè)備驅(qū)動(dòng)(初稿)_第2頁(yè)
第8章設(shè)備驅(qū)動(dòng)(初稿)_第3頁(yè)
第8章設(shè)備驅(qū)動(dòng)(初稿)_第4頁(yè)
第8章設(shè)備驅(qū)動(dòng)(初稿)_第5頁(yè)
已閱讀5頁(yè),還剩35頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第8章設(shè)備驅(qū)動(dòng)提綱1、Linux驅(qū)動(dòng)程序簡(jiǎn)介2、設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)3、Linux內(nèi)核設(shè)備模型4、同步機(jī)制5、內(nèi)存映射和管理6、工作隊(duì)列7、異步I/O8、DMA1、Linux驅(qū)動(dòng)程序簡(jiǎn)介設(shè)備驅(qū)動(dòng)程序是操作系統(tǒng)內(nèi)核和機(jī)器硬件之間的接口設(shè)備驅(qū)動(dòng)程序?yàn)閼?yīng)用程序屏蔽了硬件的細(xì)節(jié),在應(yīng)用程序看來(lái),硬件設(shè)備只是一個(gè)設(shè)備文件,應(yīng)用程序可以像操作普通文件一樣對(duì)硬件設(shè)備進(jìn)行操作Linux驅(qū)動(dòng)程序簡(jiǎn)介設(shè)備驅(qū)動(dòng)程序是內(nèi)核的一部分,它完成以下的功能:(1)對(duì)設(shè)備的初始化和釋放。(2)把數(shù)據(jù)從內(nèi)核傳送到硬件和從硬件讀取數(shù)據(jù)到內(nèi)核。(3)讀取應(yīng)用程序傳送給設(shè)備文件的數(shù)據(jù)和回送應(yīng)用程序請(qǐng)求的數(shù)據(jù)。這需要在用戶空間,內(nèi)核空間,總線以及外設(shè)之間傳輸數(shù)據(jù)。(4)檢測(cè)和處理設(shè)備出現(xiàn)的錯(cuò)誤。Linux驅(qū)動(dòng)程序簡(jiǎn)介設(shè)備的分類(lèi)字符設(shè)備無(wú)需緩沖直接讀寫(xiě)的設(shè)備,如系統(tǒng)的串口設(shè)備/dev/cua0和/dev/cua1塊設(shè)備以塊為單位進(jìn)行讀寫(xiě),典型的塊大小為512或1024字節(jié);塊設(shè)備的存取是通過(guò)buffer、cache來(lái)進(jìn)行并且可以隨機(jī)訪問(wèn),即不管塊位于設(shè)備中何處都可以對(duì)其進(jìn)行讀寫(xiě)網(wǎng)絡(luò)設(shè)備通過(guò)BSD套接口訪問(wèn)Linux驅(qū)動(dòng)程序簡(jiǎn)介設(shè)備文件Linux抽象了對(duì)硬件的處理,所有的硬件設(shè)備都可以作為普通文件一樣來(lái)看待:它們可以使用和操作文件相同的、標(biāo)準(zhǔn)的系統(tǒng)調(diào)用接口來(lái)完成打開(kāi)、關(guān)閉、讀寫(xiě)和I/O控制操作,而驅(qū)動(dòng)程序的主要任務(wù)也就是要實(shí)現(xiàn)這些系統(tǒng)調(diào)用函數(shù)Linux為文件和設(shè)備提供了一致的用戶接口。對(duì)用戶來(lái)說(shuō),設(shè)備文件與普通文件并無(wú)區(qū)別Linux驅(qū)動(dòng)程序簡(jiǎn)介主設(shè)備號(hào)和次設(shè)備號(hào)主設(shè)備號(hào)標(biāo)識(shí)該設(shè)備的種類(lèi),也標(biāo)識(shí)了該設(shè)備所使用的驅(qū)動(dòng)程序次設(shè)備號(hào)標(biāo)識(shí)使用同一設(shè)備驅(qū)動(dòng)程序的不同硬件設(shè)備Linux驅(qū)動(dòng)程序簡(jiǎn)介

Linux設(shè)備驅(qū)動(dòng)代碼的分布所有Linux的設(shè)備驅(qū)動(dòng)源碼都放在drivers目錄中,分成以下幾類(lèi):block:塊設(shè)備驅(qū)動(dòng)包括IDE(在ide.c中)驅(qū)動(dòng)。塊設(shè)備包括IDE與SCSI設(shè)備。char:包含字符設(shè)備的驅(qū)動(dòng),如ttys、串行口以及鼠標(biāo)等等Linux驅(qū)動(dòng)程序簡(jiǎn)介

Linux設(shè)備驅(qū)動(dòng)程序的特點(diǎn)(1)內(nèi)核代碼(2)內(nèi)核接口(3)內(nèi)核機(jī)制與服務(wù)(4)可加載(5)可配置(6)動(dòng)態(tài)性2、設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)Linux的設(shè)備驅(qū)動(dòng)程序與外界的接口可以分成三部分:(1)驅(qū)動(dòng)程序與操作系統(tǒng)內(nèi)核的接口(2)驅(qū)動(dòng)程序與系統(tǒng)引導(dǎo)的接口(3)驅(qū)動(dòng)程序與設(shè)備的接口設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)驅(qū)動(dòng)程序的注冊(cè)與注銷(xiāo)向系統(tǒng)增加一個(gè)驅(qū)動(dòng)程序意味著要賦予它一個(gè)主設(shè)備號(hào),這可以通過(guò)在驅(qū)動(dòng)程序的初始化過(guò)程中調(diào)用定義在fs/devices.c中的register_chrdev()函數(shù)或者fs/block_dev.c中的register_blkdev()函數(shù)來(lái)完成。而在關(guān)閉字符設(shè)備或者塊設(shè)備時(shí),則需要通過(guò)調(diào)用unregister_chrdev()或unregister_blkdev()函數(shù)從內(nèi)核中注銷(xiāo)設(shè)備,同時(shí)釋放占用的主設(shè)備號(hào)。設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)設(shè)備的打開(kāi)與釋放打開(kāi)設(shè)備是通過(guò)調(diào)用定義在include/linux/fs.h中的file_operations結(jié)構(gòu)中的函數(shù)open()來(lái)完成釋放設(shè)備是通過(guò)調(diào)用file_operations結(jié)構(gòu)中的函數(shù)release()來(lái)完成設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)設(shè)備的讀寫(xiě)操作字符設(shè)備的讀寫(xiě)操作相對(duì)比較簡(jiǎn)單,直接使用函數(shù)read()和write()就可以了塊設(shè)備的話,則需要調(diào)用函數(shù)block_read()和block_write()來(lái)進(jìn)行數(shù)據(jù)讀寫(xiě)設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)設(shè)備的控制操作通過(guò)設(shè)備驅(qū)動(dòng)程序中的函數(shù)ioctl()來(lái)完成設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)設(shè)備的輪詢和中斷處理設(shè)備執(zhí)行某個(gè)命令時(shí),如“將讀取磁頭移動(dòng)到軟盤(pán)的第42扇區(qū)上”,設(shè)備驅(qū)動(dòng)可以從輪詢方式和中斷方式中選擇一種以判斷設(shè)備是否已經(jīng)完成此命令。不支持中斷的硬件設(shè)備,讀寫(xiě)時(shí)需要輪流查詢?cè)O(shè)備狀態(tài)3、Linux內(nèi)核設(shè)備模型內(nèi)核設(shè)備模型是Linux2.6之后引進(jìn)的,是為了適應(yīng)系統(tǒng)拓?fù)浣Y(jié)構(gòu)越來(lái)越復(fù)雜,對(duì)電源管理、熱插拔支持要求越來(lái)越高等形勢(shì)下開(kāi)發(fā)的全新的設(shè)備模型。它采用sysfs文件系統(tǒng),一個(gè)類(lèi)似于/proc文件系統(tǒng)的特殊文件系統(tǒng),作用是將系統(tǒng)中的設(shè)備組織成層次結(jié)構(gòu),然后向用戶程序提供內(nèi)核數(shù)據(jù)結(jié)構(gòu)信息。Linux內(nèi)核設(shè)備模型設(shè)備模型建立的目的代碼重復(fù)最?。惶峁┤缫糜?jì)數(shù)這樣的統(tǒng)一機(jī)制;例舉系統(tǒng)中所有設(shè)備,觀察其狀態(tài),查看其連接總線;用樹(shù)的形式將全部設(shè)備結(jié)構(gòu)完整、有效地展現(xiàn),包括所有總線和內(nèi)部連接;將設(shè)備和對(duì)應(yīng)驅(qū)動(dòng)聯(lián)系起來(lái);將設(shè)備按照類(lèi)型分類(lèi);從樹(shù)的葉子向根的方向依次遍歷,確保以正確順序關(guān)閉各個(gè)設(shè)備的電源Linux內(nèi)核設(shè)備模型sysfs—設(shè)備拓?fù)浣Y(jié)構(gòu)的文件系統(tǒng)表現(xiàn)/sys|--block|--bus|--class|--dev|--devices|--firmware|--fs|--kernel|--module`--powerLinux內(nèi)核設(shè)備模型sysfs根目錄下有10個(gè)目錄,分別是:block,bus,class,dev,devices,firmware,fs,kernel,module和powerBlock目錄:其下的每個(gè)子目錄分別對(duì)應(yīng)系統(tǒng)中的一個(gè)塊設(shè)備,每個(gè)目錄又都包含該塊設(shè)備的所有分區(qū);class目錄:包含以高層功能邏輯組織起來(lái)的系統(tǒng)設(shè)備視圖;等等Linux內(nèi)核設(shè)備模型驅(qū)動(dòng)模型和sysfsLinux2.6設(shè)備驅(qū)動(dòng)模型的基本元素是設(shè)備類(lèi)結(jié)構(gòu)classes、總線結(jié)構(gòu)bus、設(shè)備結(jié)構(gòu)devices、驅(qū)動(dòng)結(jié)構(gòu)driversLinux統(tǒng)一設(shè)備模型的基本結(jié)構(gòu)類(lèi)型說(shuō)明對(duì)應(yīng)內(nèi)核數(shù)據(jù)結(jié)構(gòu)對(duì)應(yīng)/sys項(xiàng)總線類(lèi)型(BusTypes)系統(tǒng)中用于連接設(shè)備的總線structbus_type/sys/bus/*/設(shè)備(Devices)內(nèi)核識(shí)別的所有設(shè)備,依照連接它們的總線進(jìn)行組織structdevice/sys/devices/*/*/../設(shè)備類(lèi)別(DeviceClasses)系統(tǒng)中設(shè)備的類(lèi)型(聲卡,網(wǎng)卡,顯卡,輸入設(shè)備等),同一類(lèi)中包含的設(shè)備可能連接不同的總線structclass/sys/class/*/設(shè)備驅(qū)動(dòng)(DeviceDrivers)在一個(gè)系統(tǒng)中安裝多個(gè)相同設(shè)備,只需要一份驅(qū)動(dòng)程序的支持structdevice_driver/sys/bus/pic/drivers/*/Linux內(nèi)核設(shè)備模型Kobject:kobject的主要功能之一是提供一個(gè)統(tǒng)一的計(jì)數(shù)系統(tǒng)。由于kobject是“基”對(duì)象,其他對(duì)象,如device,bus,class,device_driver等容器都會(huì)將其包含,其他對(duì)象的引用計(jì)數(shù)繼承或封裝kobject的引用計(jì)數(shù)就可以了。structkobject{ constchar*name;/*短名字*/ structkobject*parent;/*表示對(duì)象的層次關(guān)系*/ structsysfs_dirent*sd;/*表示sysfs中的一個(gè)目錄項(xiàng)*/};Linux內(nèi)核設(shè)備模型結(jié)構(gòu)體kref:深入到引用計(jì)數(shù)系統(tǒng)的內(nèi)部,可以發(fā)現(xiàn)kobject的引用計(jì)數(shù)是通過(guò)kref結(jié)構(gòu)體實(shí)現(xiàn),其定義在頭文件<linux/kref.h>中:structkref{ atomic_trefcount;};Linux內(nèi)核設(shè)備模型結(jié)構(gòu)體ktype:kobject是一個(gè)抽象且基本的對(duì)象,對(duì)于一族具有共同特性的kobject,就要用ktype描述。structkobj_type{ void(*release)(structkobject*kobj); structsysfs_ops*sysfs_ops; structattribute**default_attrs;}指針指向?qū)ο笳f(shuō)明release析構(gòu)函數(shù)當(dāng)kobject引用計(jì)數(shù)減至0時(shí),調(diào)用這個(gè)析構(gòu)函數(shù)。作用是釋放所有kobject使用的內(nèi)存和做相關(guān)清理工作。sysfs_opssysfs_ops結(jié)構(gòu)體sysfs_ops結(jié)構(gòu)體包含兩個(gè)函數(shù):對(duì)屬性進(jìn)行操作的讀寫(xiě)函數(shù)show()和store()。default_attrsattribute結(jié)構(gòu)體數(shù)組這些結(jié)構(gòu)定義了kobject相關(guān)的默認(rèn)屬性。屬性描述了給定對(duì)象的特征;屬性對(duì)應(yīng)/sys樹(shù)形結(jié)構(gòu)中的葉子節(jié)點(diǎn),就是文件。Linux內(nèi)核設(shè)備模型結(jié)構(gòu)體kset:kset,是kobject對(duì)象的集合體,可以看作一個(gè)容器,把所有相關(guān)的kobject聚集起來(lái)structkset{ structlist_headlist; spinlock_tlist_lock; structkobjectkobj; structkset_uevent_ops*uevent_ops;}Linux內(nèi)核設(shè)備模型platform總線:platform總線是Linux內(nèi)核中的一個(gè)虛擬總線,使設(shè)備的管理更加簡(jiǎn)單化。目前,大部分的驅(qū)動(dòng)都是用platform總線來(lái)寫(xiě)的4、同步機(jī)制在操作系統(tǒng)中,多個(gè)內(nèi)核執(zhí)行流會(huì)在同一時(shí)間執(zhí)行,所以和多進(jìn)程多線程編程一樣,內(nèi)核也需要一些同步機(jī)制來(lái)同步各執(zhí)行單元對(duì)共享數(shù)據(jù)的訪問(wèn)。特別的,在多處理器系統(tǒng)上,更需要一些同步機(jī)制來(lái)同步不同處理器上的執(zhí)行單元對(duì)共享數(shù)據(jù)的訪問(wèn)。在Linux內(nèi)核中,包含了幾乎所有主流操作系統(tǒng)具有的同步機(jī)制,由于本文采用的是2.6內(nèi)核,它包括:同步鎖、信號(hào)量、原子操作和完成事件。同步機(jī)制同步鎖自旋鎖(Spinlock)讀寫(xiě)鎖(rmlock)

RCU鎖Seqlock同步機(jī)制信號(hào)量Linux內(nèi)核的信號(hào)量在概念和原理上與用戶態(tài)的IPC機(jī)制信號(hào)量是一樣的,但是不能用在內(nèi)核之外,它是一種睡眠鎖當(dāng)一個(gè)任務(wù)試圖獲得已被占用的信號(hào)量時(shí),會(huì)進(jìn)入一個(gè)等待隊(duì)列,然后睡眠當(dāng)持有該信號(hào)量的進(jìn)程釋放信號(hào)量后,位于等待隊(duì)列的一個(gè)任務(wù)就會(huì)被喚醒,這個(gè)任務(wù)獲得信號(hào)量同步機(jī)制讀寫(xiě)信號(hào)量在應(yīng)用讀寫(xiě)信號(hào)量的場(chǎng)景中,訪問(wèn)者被細(xì)分為兩類(lèi),一種是讀者,另一種是寫(xiě)者讀者在擁有讀寫(xiě)信號(hào)量期間,對(duì)該讀寫(xiě)信號(hào)量保護(hù)的共享資源只能進(jìn)行讀訪問(wèn)如果某個(gè)任務(wù)同時(shí)需要讀和寫(xiě),則被歸類(lèi)為寫(xiě)者,它在對(duì)共享資源訪問(wèn)之前須先獲得寫(xiě)者身份,寫(xiě)者在不需要寫(xiě)訪問(wèn)的情況下將被降級(jí)為讀者同步機(jī)制原子操作原子操作是指該操作在執(zhí)行完畢前絕不會(huì)被任何其他任務(wù)或時(shí)間打斷,換句話說(shuō),它是最小的執(zhí)行單位,不會(huì)有比它更小的執(zhí)行單位原子的概念使用的是物理學(xué)里的物質(zhì)微粒的概念同步機(jī)制完成事件(completion)完成事件是一種簡(jiǎn)單的同步機(jī)制,表示“thingsmayproceed”,它適用于需要睡眠和喚醒的情景如果要在任務(wù)中實(shí)現(xiàn)簡(jiǎn)單睡眠直到其它進(jìn)程完成某些處理過(guò)程為止,可以采用完成事件,它不會(huì)引起資源競(jìng)爭(zhēng)如果要使用completion,需要包含<linux/completion.h>,同時(shí)創(chuàng)建類(lèi)型為structcompletion的變量同步機(jī)制時(shí)間測(cè)量時(shí)間流失(jiffies)獲知當(dāng)前時(shí)間延后執(zhí)行內(nèi)核定時(shí)器5、內(nèi)存映射和管理物理地址映射到虛擬地址每一種外設(shè)的訪問(wèn)都是通過(guò)讀寫(xiě)設(shè)備上的寄存器來(lái)進(jìn)行,包括控制寄存器、狀態(tài)寄存器和數(shù)據(jù)寄存器三大類(lèi)CPU對(duì)I/O端口的編址方式有兩種I/O映射方式內(nèi)存映射方式內(nèi)存映射和管理內(nèi)核空間映射到用戶空間內(nèi)存映射是現(xiàn)代Unix最有趣的特性之一。對(duì)于驅(qū)動(dòng)來(lái)說(shuō),內(nèi)存映射可用來(lái)提供用戶程序?qū)υO(shè)備內(nèi)存的直接存取。如果想在用戶空間訪問(wèn)內(nèi)核地址,可以采用mmap方法。用戶空間的應(yīng)用程序通過(guò)映射可以直接訪問(wèn)設(shè)備的I/O存儲(chǔ)區(qū)或DMA緩沖。映射一個(gè)設(shè)備是指關(guān)聯(lián)一些用戶空間地址到設(shè)備內(nèi)存。這樣,無(wú)論何時(shí)程序在給定范圍內(nèi)讀寫(xiě),實(shí)際上是在存取設(shè)備。6、工作隊(duì)列工作隊(duì)列(workqueue)是linux內(nèi)核將工作退后執(zhí)行的機(jī)制tasklets不同的是工作隊(duì)列把推后的工作交給內(nèi)核線程去執(zhí)行工作隊(duì)列的優(yōu)勢(shì)就是允許重新調(diào)度甚至睡眠2.6內(nèi)核開(kāi)始引入工作隊(duì)列7、異步I/OLinux的異步I/O(AIO)在版本linux2.5版本內(nèi)核中首次出現(xiàn)。首先來(lái)看一下Linux的I/O機(jī)制經(jīng)歷的幾個(gè)階段:(1)同步阻塞I/O:用戶進(jìn)程進(jìn)行I/O操作,一直阻塞到I/O操作完成為止;(2)同步非阻塞I/O:用戶程序可以通過(guò)設(shè)置文件描述符的屬性O(shè)_NONBLOCK,I/O操作可以立即返回,但是并不保證I/O操作成功。(3)異步事件阻塞I/O:用戶進(jìn)程可以對(duì)I/O事件進(jìn)行阻塞,但是I/O操作并不阻塞。通過(guò)select/poll/epoll等函數(shù)調(diào)用來(lái)達(dá)到此目的。(4)異步事件非阻塞I/O:也叫做異步I/O(AIO),用戶程序可以通過(guò)向內(nèi)核發(fā)出I/O請(qǐng)求命令,不用等帶I/O事件真正發(fā)生,可以繼續(xù)做另外的事情,等I/O操作完成,內(nèi)核會(huì)通過(guò)函數(shù)回調(diào)或者信號(hào)機(jī)制通知用戶進(jìn)程。這樣很大程度提高了系統(tǒng)吞吐量。8、DMADMA(DirectMemoryAccess),直接內(nèi)存存取,是解決快速數(shù)據(jù)訪問(wèn)的有效方法。DMA控制器可以不需要處理器的干預(yù),在設(shè)備和系統(tǒng)內(nèi)存高速傳輸數(shù)據(jù)DMADMA數(shù)據(jù)傳輸DMA的傳送數(shù)據(jù)有三個(gè)階段組成:傳送前的預(yù)處理:向DMA控制器發(fā)送設(shè)備識(shí)別信號(hào),啟動(dòng)設(shè)備,測(cè)試設(shè)備運(yùn)行狀態(tài)

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論