裝置驅動程式為什麼和普通應用程式許多差異

2022-01-15 11:07:48 字數 5889 閱讀 3462

1樓:遠巨集

驅動程式是很底層的,危險性很高的,直接跟硬體打交道的,在作業系統層級下面而普通的應用程式層級是高於作業系統的,需要通過作業系統去呼叫底層的東西。

驅動程式,可以說相當於硬體的介面,作業系統只能通過這個介面,才能控制硬體裝置的工作,假如某裝置的驅動程式未能正確安裝,便不能正常工作。

2樓:藺小夕

都是應用軟體的一種,兩個程式的作用:驅動程式是連線硬體的必不可少的程式,相當於硬體和系統之間的橋樑;而應用程式是在驅動程式的基礎上,有了硬體的連線啟用,才能更好的應用發揮硬體的作用。區別在於兩個程式所發揮的作用不同。

驅動程式取決於硬體和作業系統。它們通常提供任何必要的非同步時間相關硬體介面所需的中斷處理。因此,差不多所有人都在使用者模式下執行。

然而,正如第二段所述,為了防止應用程式破壞關鍵os資料,使用者應用程式必然會在使用者空間中執行。

此外,並非所有驅動程式都直接與裝置通訊。對於給定的i/o請求(如從裝置讀取資料),通常會有多個驅動程式分層堆疊,並參與請求。直接與裝置通訊的堆疊中的一個驅動程式稱為功能驅動程式;執行輔助處理的驅動程式稱為過濾器驅動程式。

linux裝置驅動程式與應用層程式的不同點和相互關係

3樓:程華衣慕梅

linux字元驅動裝置,本身就是工作在核心層啊!

驅動裝置的應用測試程式,才是工作在應用層,通過基本檔案操作如open、read、write、close等函式操作驅動裝置!

4樓:匿名使用者

linux驅動程式是硬體裝置和應用程式的介面,有了驅動程式,應用程式不用關心底層的東西,通過驅動提供的介面來操作硬體。驅動是核心的一部分,執行在核心空間,而應用程式執行在使用者程序空間,使用者程序是不能直接訪問核心空間的。

5樓:匿名使用者

我最近也在看這方面的資料,樓上的回答的應該差不多的。

補充一些,在《linux裝置驅動程式》裡面介紹應用程式有一個組織策略的功能,驅動程式在編寫的時候就是提供相關硬體裝置的機能。就是說驅動程式不要加入額外的怎麼去邏輯上使用硬體的部分,驅動程式需要實現好以下功能:

1.對裝置初始化和釋放;

2.把資料從核心傳送到硬體和從硬體讀取資料.;

3.讀取應用程式傳送給裝置檔案的資料和回送應用程式請求的資料.;

4.檢測和處理裝置出現的錯誤。

如果要更加詳細的瞭解,建議去買這本書看看。

應用程式怎麼和核心流驅動程式互動

6樓:去了不好意思

linux是unix作業系統的一種變種,在linux下編寫驅動程式的原理和思想完全類似於其他的unix系統,但它dos或window環境下的驅動程式有很大的區別。在linux環境下設計驅動程式,思想簡潔,操作方便,功能也很強大,但是支援函式少,只能依賴kernel中的函式,有些常用的操作要自己來編寫,而且除錯也不方便。以下的一些文字主要**於khg,johnsonm的writelinuxdevicedriver,brennan'sguidetoinlineassembly,thelinuxa-z,還有清華bbs上的有關devicedriver的一些資料。

一、linuxdevicedriver的概念  系統呼叫是作業系統核心和應用程式之間的介面,裝置驅動程式是作業系統核心和機器硬體之間的介面。裝置驅動程式為應用程式遮蔽了硬體的細節,這樣在應用程式看來,硬體裝置只是一個裝置檔案,應用程式可以象操作普通檔案一樣對硬體裝置進行操作。裝置驅動程式是核心的一部分,它完成以下的功能:

  1、對裝置初始化和釋放。  2、把資料從核心傳送到硬體和從硬體讀取資料。  3、讀取應用程式傳送給裝置檔案的資料和回送應用程式請求的資料。

  4、檢測和處理裝置出現的錯誤。  在linux作業系統下有三類主要的裝置檔案型別,一是字元裝置,二是塊裝置,三是網路裝置。字元裝置和塊裝置的主要區別是:

在對字元裝置發出讀/寫請求時,實際的硬體i/o一般就緊接著發生了,塊裝置則不然,它利用一塊系統記憶體作緩衝區,當使用者程序對裝置請求能滿足使用者的要求,就返回請求的資料,如果不能,就呼叫請求函式來進行實際的i/o操作。塊裝置是主要針對磁碟等慢速裝置設計的,以免耗費過多的cpu時間來等待。  已經提到,使用者程序是通過裝置檔案來與實際的硬體打交道。

每個裝置檔案都都有其檔案屬性(c/b),表示是字元裝置還是塊裝置?另外每個檔案都有兩個裝置號,第一個是主裝置號,標識驅動程式,第二個是從裝置號,標識使用同一個裝置驅動程式的不同的硬體裝置,比如有兩個軟盤,就可以用從裝置號來區分他們。裝置檔案的的主裝置號必須與裝置驅動程式在登記時申請的主裝置號一致,否則使用者程序將無法訪問到驅動程式。

  最後必須提到的是,在使用者程序呼叫驅動程式時,系統進入核心態,這時不再是搶先式排程。也就是說,系統必須在你的驅動程式的子函式返回後才能進行其他的工作。如果你的驅動程式陷入死迴圈,不幸的是你只有重新啟動機器了,然後就是漫長的fsck。

  讀/寫時,它首先察看緩衝區的內容,如果緩衝區的資料未被處理,則先處理其中的內容。  如何編寫linux作業系統下的裝置驅動程式  二、例項剖析我們來寫一個最簡單的字元裝置驅動程式。雖然它什麼也不做,但是通過它可以瞭解linux的裝置驅動程式的工作原理。

把下面的c**輸入機器,你就會獲得一個真正的裝置驅動程式。#define__no_version__#include#include  charkernel_version=uts_release;  這一段定義了一些版本資訊,雖然用處不是很大,但也必不可少。johnsonm說所有的驅動程式的開頭都要包含,一般來講最好使用。

  由於使用者程序是通過裝置檔案同硬體打交道,對裝置檔案的操作方式不外乎就是一些系統呼叫,如open,read,write,close…,注意,不是fopen,fread,但是如何把系統呼叫和驅動程式關聯起來呢?這需要了解一個非常關鍵的資料結構:structfile_operations  這個結構的每一個成員的名字都對應著一個系統呼叫。

使用者程序利用系統呼叫在對裝置檔案進行諸如read/write操作時,系統呼叫通過裝置檔案的主裝置號找到相應的裝置驅動程式,然後讀取這個資料結構相應的函式指標,接著把控制權交給該函式。這是linux的裝置驅動程式工作的基本原理。既然是這樣,則編寫裝置驅動程式的主要工作就是編寫子函式,並填充file_operations的各個域。

  下面就開始寫子程式。#include#include#include#include#include#includeunsignedinttest_major=0;staticintread_test(structinode*node,structfile*file,char*buf,intcount)returncount;}這個函式是為read呼叫準備的。當呼叫read時,read_test()被呼叫,它把使用者的緩衝區全部寫1。

buf是read呼叫的一個引數。它是使用者程序空間的一個地址。但是在read_test被呼叫時,系統進入核心態。

所以不能使用buf這個地址,必須用__put_user(),這是kernel提供的一個函式,用於向使用者傳送資料。另外還有很多類似功能的函式。請參考robert著的《linux核心設計與實現》(第二版)。

然而,在向使用者空間拷貝資料之前,必須驗證buf是否可用。這就用到函式verify_area。staticintwrite_tibet(structinode*inode,structfile*file,constchar*buf,intcount)staticintopen_tibet(structinode*inode,structfile*file)staticvoidrelease_tibet(structinode*inode,structfile*file)  這幾個函式都是空操作。

實際呼叫發生時什麼也不做,他們僅僅為下面的結構提供函式指標。structfile_operationstest_fops=;  這樣,裝置驅動程式的主體可以說是寫好了。現在要把驅動程式嵌入核心。

驅動程式可以按照兩種方式編譯。一種是編譯進kernel,另一種是編譯成模組(modules),如果編譯進核心的話,會增加核心的大小,還要改動核心的原始檔,而且不能動態的解除安裝,不利於除錯,所以推薦使用模組方式。intinit_module(void)read(testdev,buf,10);for(i=0;i<10;i++)printf("%d\n",buf[i]);close(testdev);}  編譯執行,看看是不是列印出全1?

  以上只是一個簡單的演示。真正實用的驅動程式要複雜的多,要處理如中斷,dma,i/oport等問題。這些才是真正的難點。

請看下節,實際情況的處理。如何編寫linux作業系統下的裝置驅動程式 三、裝置驅動程式中的一些具體問題  1。i/oport。

  和硬體打交道離不開i/oport,老的isa裝置經常是佔用實際的i/o埠,在linux下,作業系統沒有對i/o口遮蔽,也就是說,任何驅動程式都可對任意的i/o口操作,這樣就很容易引起混亂。每個驅動程式應該自己避免誤用埠。  有兩個重要的kernel函式可以保證驅動程式做到這一點。

  1)check_region(intio_port,intoff_set)  這個函式察看系統的i/o表,看是否有別的驅動程式佔用某一段i/o口。  引數1:i/o埠的基地址,  引數2:

i/o埠占用的範圍。  返回值:0沒有佔用,非0,已經被佔用。

  2)request_region(intio_port,intoff_set,char*devname)  如果這段i/o埠沒有被佔用,在我們的驅動程式中就可以使用它。在使用之前,必須向系統登記,以防止被其他程式佔用。登記後,在/proc/ioports檔案中可以看到你登記的i/o口。

  引數1:io埠的基地址。  引數2:

io埠占用的範圍。  引數3:使用這段io地址的裝置名。

  在對i/o口登記後,就可以放心地用inb(),outb()之類的函來訪問了。在一些pci裝置中,i/o埠被對映到一段記憶體中去,要訪問這些埠就相當於訪問一段記憶體。經常性的,我們要獲得一塊記憶體的實體地址。

  2。記憶體操作  在裝置驅動程式中動態開闢記憶體,不是用malloc,而是kmalloc,或者用get_free_pages直接申請頁。釋放記憶體用的是kfree,或free_pages。

請注意,kmalloc等函式返回的是實體地址!  注意,kmalloc最大隻能開闢128k-16,16個位元組是被頁描述符結構佔用了。  記憶體對映的i/o口,暫存器或者是硬體裝置的ram(如視訊記憶體)一般佔用f0000000以上的地址空間。

在驅動程式中不能直接訪問,要通過kernel函式vremap獲得重新對映以後的地址。  另外,很多硬體需要一塊比較大的連續記憶體用作dma傳送。這塊程式需要一直駐留在記憶體,不能被交換到檔案中去。

但是kmalloc最多隻能開闢128k的記憶體。  這可以通過犧牲一些系統記憶體的方法來解決。    3。

中斷處理  同處理i/o埠一樣,要使用一箇中斷,必須先向系統登記。intrequest_irq(unsignedintirq,void(*handle)(int,void*,structpt_regs*),unsignedintlongflags,constchar*device);irq:是要申請的中斷。

handle:中斷處理函式指標。flags:

sa_interrupt請求一個快速中斷,0正常中斷。device:裝置名。

  如果登記成功,返回0,這時在/proc/interrupts檔案中可以看你請求的中斷。  4。一些常見的問題。

對硬體操作,有時時序很重要(關於時序的具體問題就要參考具體的裝置晶片手冊啦!比如網絡卡晶片rtl8139)。但是如果用c語言寫一些低階的硬體操作的話,gcc往往會對你的程式進行優化,這樣時序會發生錯誤。

如果用匯編寫呢,gcc同樣會對彙編**進行優化,除非用volatile關鍵字修飾。最保險的法是禁止優化。這當然只能對一部分你自己編寫的**。

如果對所有的**都不優化,你會發現驅動程式根本無法裝載。這是因為在編譯驅動程式時要用到gcc的一些擴充套件特性,而這些擴充套件特性必須在加了優化選項之後才能體現出來。寫在後面:

學習linux確實不是一件容易的事情,因為要付出很多精力,也必須具備很好的c語言基礎;但是,學習linux也是一件非常有趣的事情,它裡面包含了許多高手的智慧和「幽默」,這些都需要自己親自動手才能體會到,o(∩_∩)o~哈哈!

為什麼應用程式突然停止工作,為什麼應用程式突然停止工作

這是vista系統特有的一個工具叫uac,關閉這個功能就可以了,關閉方法如下 控制面板 使用者帳戶 開啟或關閉使用者賬戶控制 取消使用使用者賬戶控制 uac 幫助保護您的計算機。據微軟說uac是一件防護惡意軟體 病毒 木馬 蠕蟲及間諜軟體的神兵利器,可以幫助人們象安全專家一樣避免執行不明 的郵件附件...

主機板還要安裝驅動程式嗎,為什麼主機板也要驅動!是所有主機板都要驅動嗎!?

可以不安裝,但是安裝後主機板更穩定,效能更好了。主機板驅動程式的重要性 由於目前硬體更新換代的速度遠遠快於軟體的速度,所以在使用新主機板的時候往往會帶來一系列的相容問題。如很多主機板晶片組無法被作業系統正確識別,這直接造成了本來能夠支援的新技術不能正常使用以及相容性問題大量出現。主機板驅動程式不僅解...

為什麼skype老是應用程式錯誤啊

應用程式錯誤是怎麼回事?所中的病毒木馬不同,應用程式出現錯誤的提示也不盡相同。一般的情況是原來能正常執行的軟體突然一開啟就報告 應用程式錯誤,需要關閉 應用程式錯誤,記憶體地址不能read 應用程式錯誤,位於地址 等等 造成應用程式錯誤 該記憶體不能為read的原因 1.病毒木馬破壞 2.應用程式元...