ARMLINUX網絡卡驅動分析

2021-05-27 21:38:30 字數 3337 閱讀 5903

armlinux網絡卡驅動分析

一、網路裝置驅動結構

1網路協議介面層

2網路裝置介面層

3裝置驅動功能層

4網路裝置與媒介層

二、網路協議介面層

1功能:給上層協議提供透明的資料報傳送和接收介面

2定義在/include/linux/netdevice.h中

3函式原型:

int     dev_queue_xmit(struct sk_buff *skb);

int            netif_rx(struct sk_buff *skb);

4        sk_buff含義為套接字緩衝區

三、套接字

1  sk_buff結構體定義在/linux/skbuff.h中

2 套接字在所有網路作業系統和網路應用程式中都是必不可少的,它是網路通訊中應用程序和網路協議的介面

3 在linux中,套接字屬於檔案系統的一部分,網路 通訊可以被看作是對檔案的讀取

四、linux網路層次模型

五、網路裝置介面層

1  定義了net_device結構體

2 它包含網路裝置的屬性描述和操作介面,寫驅動時只需填充net_device的具體成員並註冊即可實現硬體操作函式與核心的掛接

裝置驅動功能層 & 網路裝置與媒介層

3        net_device結構體成員(屬性和函式指標)需要被裝置驅動功能層的具體數值和函式賦予,並且在這一層定義中斷處理函式,負責讀取硬體上接收的資料報並傳給上層協議。

網路裝置與媒介層直接對應於實際的硬體裝置

分析驅動程式

4        驅動程式包括裝置的註冊與註消,裝置的初始化,裝置的開啟與釋放,資料傳送與接收,統計網路聯接狀態資料等

5        這裡以我們常用的cirrus公司的cs8900網絡卡為例對程式加以分析.檔案為/drivers/net/cs89x0.c

eets

/old/cs8900.pdf

六、裝置的註冊與註消

1  在/include/linux/netdevice.h中定義了許多api介面

2        裝置的註冊與登出定義如下:

int  register_netdev(struct net_device *dev)

void unregister_netdev(struct net_device *dev)

3        net_device資料結構的地位很重要

七、裝置的初始化

1 程式的初始化由net_device結構體中的init()函式完成,這個函式將在net_device被註冊時自動被呼叫.init()函式在程式中對應於cs89x0_probe()函式:

struct net_device * __init cs89x0_probe(int unit)

4  for (port = netcard_portlist; *port; port++) { /*netcard_portlist為unsigned int型陣列,在cs89x0.c檔案中定義,裡面列出了cs8900可能占用空間的起始位址,這些位址在cs89x0_probe1函式中用於向核心申請*/

if (cs89x0_probe1(dev, *port, 0) == 0)  /*若探測成功返回, 驗證了網絡卡的存在,並獲取cs8900所使用的硬體資源*/

2        下來才是真正的探測工作

static int __init

cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) 

(1)初始化裝置結構

(2)讀取晶元型別並判斷型號

(3)完成net_device裝置結構體的初始化,賦值其屬性和函式指標

七、網路裝置的開啟與釋放

1定義在/include/linux/netdevice.h中

2開啟函式void netif_start_queue(struct net_device *dev)

3 開啟函式完成使能裝置使用的硬體資源,申請i/o區域,中斷和dma通道,啟用裝置傳送佇列

4關閉函式為void netif_stop_queue(struct net_device *dev)

八、傳送資料

1向控制暫存器tx_cmd暫存器寫入傳送命令

2將傳送資料長度寫入tx_leng暫存器

3讀取packetpage空間內的pp_busst暫存器,確定其第8位被設定為ready_for_tx_now ,即裝置處於準備傳送狀態

4將要傳送的資料迴圈寫入暫存器.

caution!!這裡有個自旋鎖spin_lock_irq(&lp->lock)的應用

九、接收資料

1   cs8900的資料報接收流程由中斷引發,在中斷服務程式中會判斷中斷的型別,如果是接收到資料報中斷,則完成套接字緩衝區的建立和填充,並呼叫netif_rx()函式將套接字緩衝區傳遞給上層協議.中斷函式為irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs * regs)

2     /*讀取中斷事件型別*/

while ((status = readword(dev, isq_port))) {

if (net_debug > 4)printk(「%s: event=%04x\n」, dev->name, status);

handled = 1;

switch(status & isq_event_mask) {

case isq_receiver_event:  /*獲得資料報*/

net_rx(dev);  /*當網絡卡中斷為接收中斷時,呼叫 net_rx()函式完成資料報的獲取與上層協議傳遞*/

break; 

3   void net_rx(struct net_device *dev)

(1).          接收資料報長度

(2).          分配新的套接字緩衝區和資料緩衝區

(3).          讀資料報放入緩衝區

(4).          解析協議型別

(5).          這兩行統計接收資料報數和接收位元組數

lp->stats.rx_packets++;

lp->stats.rx_bytes += length;

十、總結

1   網路裝置驅動體系結構的層次化設計實現了對上層協議介面的統一和硬體驅動的對下層多樣化 硬體裝置的可適應,這也正是驅動程式所要起到的主要作用.

2  對原始碼的分析可以發現net_device結構體的定義非常重要,它內部的屬性和函式指標在驅動 程式中負擔了大部分工作.

3  同時需要留意的是套接字緩衝區sk_buff,它承載了所有資料流的傳輸.

ARM Linux驅動開發環境

目的 梳理arm linux驅動開發所需的環境和流程,記錄遇到的問題。環境介紹 pc機 編寫驅動程式和測試 伺服器 編譯驅動程式生成.ko檔案,編譯測試 生成執行程式 單板 jz2440 準備工作 linux核心 linux 2.6.22.6以及對應的補丁檔案 工具鏈 gcc version 3.4...

ARM Linux驅動 ADC驅動(中斷方式)

硬體平台 fl2440 核心版本 2.6.28 主機平台 ubuntu 11.04 核心版本 2.6.39 這個驅動寫了好久,因為原來的linux核心編譯的時候將觸控螢幕驅動編譯進核心了,而觸控螢幕驅動裡的adc中斷在註冊的時候型別選擇的是 irqf sample random,不是共享型別,所以,...

ARM Linux驅動 ADC驅動(中斷方式)

硬體平台 fl2440 核心版本 2.6.28 主機平台 ubuntu 11.04 核心版本 2.6.39 這個驅動寫了好久,因為原來的linux核心編譯的時候將觸控螢幕驅動編譯進核心了,而觸控螢幕驅動裡的adc中斷在註冊的時候型別選擇的是 irqf sample random,不是共享型別,所以,...