3.1 中斷共享
linux系統執行幾個裝置共享同乙個中斷。需要共享的話,在申請的時候指明共享方式。系統提供的request_irq()呼叫的定義:
int request_irq(unsigned int irq,
void (*handler)(int irq, void *dev_id, struct pt_regs *regs),
unsigned long irqflags,
const char * devname,
void *dev_id);
如果共享中斷,irqflags設定sa_shirq屬性,這樣就允許別的裝置申請同乙個中斷。需要注意所有用到這個中斷的裝置在呼叫request_irq()都必須設定這個屬性。系統在**每個中斷處理程式時,可以用dev_id這個引數找到相應的裝置。系統在**每個中斷處理程式時,可以用dev_id這個引數找到相應的裝置。一般dev_id就設為device結構本身。系統處理共享中斷是用各自的dev_id引數依次呼叫每乙個中斷處理程式。
3.2 硬體傳送忙時的處理
主cpu的處理能力一般比網路傳送要快,所以經常會遇到系統有資料要發,但上一包資料網路裝置還沒傳送完。因為在linux裡網路裝置驅動程式一般不做資料快取,不能傳送的資料都是通知系統傳送不成功,所以必須要有乙個機制在硬體不忙時及時通知系統接著傳送下面的資料。
網管網bitscn.com
一般對傳送忙的處理在前面裝置的傳送方法(hard_start_xmit)裡已經描述過,即如果傳送忙,置tbusy為1。處理完傳送資料後,在傳送結束中斷裡清tbusy,同時用mark_bh()呼叫通知系統繼續傳送。
但在具體實現我的驅動程式時發現,這樣的處理系統好象並不能及時地知道硬體已經空閒了,即在mark_bh()以後,系統要等一段時間才會接著傳送。造成傳送效率很低。2m線路只有10%不到的使用率。核心版本為2.0.35。
我最後的實現是不把tbusy置1,讓系統始終認為硬體空閒,但是報告傳送不成功。系統會一直嘗試重發。這樣處理就執行正常了。但是遍循核心原始碼中的網路驅動程式,似乎沒有這樣處理的。不知道癥結在**。
3.3 流量控制(flow control)
網路資料的傳送和接收都需要流量控制。這些控制是在系統裡實現的,不需要驅動程式做工作。每個裝置資料結構裡都有乙個引數dev->tx_queue_len,這個引數標明傳送時最多快取的資料報。在linux系統裡乙太網裝置(10/100mbps)標明傳送時最多快取的資料報。在linux系統裡乙太網裝置(10/100mbps)tx_queue_len一般設定為100,序列線路(非同步串列埠)為10。實際上如果看原始碼可以知道,設定了dev->tx_queue_len並不是為快取這些資料申請了空間。這個引數只是在收到協議層的資料報時判斷傳送佇列裡的資料是不是到了tx_queue_len的限度,以決定這一包資料加不加進傳送佇列。傳送時另乙個方面的流控是更高層協議的傳送視窗(tcp協議裡就有傳送視窗)。達到了視窗大小,高層協議就不會再傳送資料。
中國網管論壇bbs.bitscn.com
接收流控也分兩個層次。netif_rx()快取的資料報有限制。另外高層協議也會有乙個最大的等待處理的資料量。
傳送和接收流控處理在net/core/dev.c的do_dev_queue_xmit()和netif_rx()中。
3.4 除錯
很多linux的驅動程式都是編譯進核心的,形成乙個大的核心檔案。但對除錯來說,這是相當麻煩的。除錯驅動程式可以用module方式載入。支援模組方式的驅動程式必須提供兩個函式:int init_module(void)和void cleanup_module(void)。init_module()在載入此模組時呼叫,在這個函式裡可以register_netdev()註冊裝置。init_module()返回0表示成功,返回負表示失敗。cleanup_module()在驅動程式被解除安裝時呼叫,清除占用的資源,呼叫unregister_netdev()。
模組可以動態地載入、解除安裝。在2.0.xx版本裡,還有kerneld自動載入模組,但是2.2.xx中已經取消了kerneld。手工載入使用insmod命令,解除安裝用rmmod命令,看核心中的模組用lsmod命令。
編譯驅動程式用gcc,主要命令列引數-dkernel -dmodule。並且作為模組載入的驅動程式,只編譯成obj形式(加-c引數)。編譯好的目標文放/lib/modules/2.x.xx/misc下,在啟動檔案裡用insmod載入。
四.進一步的閱讀
linux程式設計資料可以從網上獲得。這就是開放源**的好處。並且沒有什麼「未公開的秘密」。我編寫驅動程式時參閱的主要資料報括:
linux核心源**
《the linux kernel hackers guide》by michael k. johnson
《linux kernel module programming guide》by ori pomerantz
《linux下的裝置驅動程》by olly in bbs水木清華站
可以選擇乙個模板作為開始,核心源**裡有乙個網路驅動程式的模板,drivers/net/skeleton.c。裡面包含了驅動程式的基本內容。但這個模板是以乙太網裝置為物件的,乙太網的處理在linux系統裡有特殊「待遇」,所以如果不是乙太網裝置,有些細節上要注意,主要在初始化程式裡。
最後,多參照別人寫的程式,聽聽其他開發者的經驗之談大概是最有效的幫助了。
Linux驅動程式編寫
linux作業系統網路驅動程式編寫 一.linux系統裝置驅動程式概述 1.1 linux裝置驅動程式分類 1.2 編寫驅動程式的一些基本概念 二.linux系統網路裝置驅動程式 2.1 網路驅動程式的結構 2.2 網路驅動程式的基本方法 2.3 網路驅動程式中用到的資料結構 2.4 常用的系統支援...
Linux網路驅動程式編寫 二 4
linux網路驅動程式編寫 二 4 2001 06 15 bordi 飲水思源站12 3 4 5 2.2.6 硬體幀頭 hard header 硬體一般都會在上層資料傳送之前加上自己的硬體幀頭,比如乙太網 ether 就有14位元組的幀頭。這個幀頭是加在上層ip ipx等資料報的前 面的。驅動程式提...
編寫Linux裝置驅動程式教程
序言 linux是unix作業系統的一種變種,在linux下編寫驅動程式的原理和思想完全類似於其他的unix系統,但它dos或window環境下的驅動程式有很大的區別。在linux環境下設計驅動程式,思想簡潔,操作方便,功能也很強大,但是支援函式少,只能依賴kernel中的函式,有些常用的操作要自己...