LDD3讀書筆記(第13章 網路裝置驅動)

2021-06-09 12:23:08 字數 3948 閱讀 1021

這個小節給出了本章介紹過的概念的快速參考,同時解釋了驅動程式應該包含的每個標頭檔案。但是net_device和sk_buff結構的成員不會在這裡重複。

#include

這個標頭檔案儲存有net_device和net_device_stats結構的定義,幷包含了網路驅動程式需要的其他幾個標頭檔案。

struct net_device *alloc_netdev(int sizeof_priv,char *name,void (*setup)(struct net_device *));

struct net_device *alloc_etherdev(int sizeof_priv);

void free_netdev(struct net_device *dev);

分配和釋放net_device結構的函式。

int register_netdev(struct net_device *dev);

void unregister_netdev(struct net_device *dev);

註冊和登出乙個網路裝置。

void *netdev_priv(struct net_device *dev);

獲得指向網路裝置結構中驅動程式私有資料區指標的函式。

struct net_device_stats;

儲存裝置統計資訊的結構。

netif_start_queue(struct net_device *dev);

netif_stop_queue(struct net_device *dev);

netif_wake_queue(struct net_device *dev);

上述函式控制外發資料報向驅動程式的傳遞。在呼叫netif_start_queue之前,不會傳輸任何資料報。netif_stop_queue暫停傳輸,而netif_wake_queue重新啟動佇列並通知網路層重新啟動資料報的傳輸。

skb_shinfo(struct sk_buff *skb);

提供對資料報緩衝區中「共享資訊」訪問的巨集。

void netif_rx(struct sk_buff *skb);

呼叫(包括中斷期間)這個函式可通知核心已經接收到乙個資料報,冰封裝入乙個套接字緩衝區。

void netif_rx_schedule(dev);

呼叫該函式通知核心資料報已經存在,並且在介面上啟動輪詢機制;它只在napi驅動程式中使用。

int netif_receive_skb(struct sk_buff *skb);

void netif_rx_complete(struct net_device *dev);

這兩個函式只在napi驅動程式中使用。napi中的netif_receive_skb函式與netif_rx等價;它將資料報傳送給核心。當napi驅動程式耗盡了為接收資料報準備的記憶體,則它將重新啟動中斷,然後呼叫netif_rx_complete終止輪詢函式。

#include

netdevice.h中包含該標頭檔案。在該檔案中宣告了介面標誌(iff_macros)和ifmap結構,在網路驅動程式的ioctl實現中,其扮演了重要角色。

void netif_carrier_off(struct net_device *dev);

void netif_carrier_on(struct net_device *dev);

int netif_carrier_ok(struct net_device *dev);

前兩個函式告訴核心在指定介面上是否存在載波訊號。netif_carrier_ok檢查載波狀態作為在device結構中的應答。

#include

eth_alen

eth_p_ip

struct ethhdr;

netdevice.h中包含該標頭檔案。if_ether.h中定義了所有的eth_巨集、用來表示octet的長度(比如位址長度)和網路協議(比如ip)。它還定義了ethhdr結構。

#include

定義了sk_buff及其相關的結構,同時定義了許多作用於緩衝區的內聯函式。該標頭檔案包含在netdevice.h中。

struct sk_buff *alloc_skb(unsigned int len,int priority);

struct sk_buff *dev_alloc_skb(unsigned int len);

void kfree_skb(struct sk_buff *skb);

void dev_kfree_skb(struct sk_buff *skb);

void dev_kfree_skb_irq(struct sk_buff *skb);

void dev_kfree_skb_any(struct sk_buff *skb);

分配和釋放套接字緩衝區的函式。因此驅動程式通常使用有dev_字首的變種。

unsigned char *skb_put(struct sk_buff *skb,int len);

unsigned char *__skb_put(struct sk_buff *skb,int len);

unsigned char *skb_push(struct sk_buff *skb,int len);

unsigned char *__skb_push(struct sk_buff *skb,int len);

將資料新增到skb的函式;skb_put將資料放在skb的末尾,而skb_push將資料放在開頭,常用的版本還負責檢查是否有足夠的空間存放資料;而有雙下劃線字首的版本不進行該項檢查。

int skb_headroom(stryct sk_buff *skb);

int skb_tailroom(struct sk_buff *skb);

void skb_reserve(struct sk_buff *skb,int len);

在skb中實現空間管理的函式。skb_headroom和skb_tailroom分別返回在skb的開頭和結尾,還有多少空間可用。skb_reserve用於在skb開頭部分保留空間,保留的空間必須唯恐。

unsigned char *skb_pull(struct sk_buff *skb,int len);

skb_pull通過調整內部指標而「刪除」skb內的資料。

int skb_is_nonlinear(struct sk_buff *skb);

如果使用分散/聚集i/o,並且skb分離成多個資料片段,則該函式返回真實值。

int skb_headlen(struct sk_buff *skb);

返回skb中skb->data 的第乙個段的長度。

void *kmap_skb_frag(skb_frag_t *frag);

void kunmap_skb_frag(void *vaddr);

提供對非線性skb中的資料片段的直接訪問。

#include

void ether_setup(struct net_device *dev);

為乙太網驅動程式設定大部分通用裝置方法的函式。它還設定了dev->flags。如果裝置名稱的第乙個字元為空,或者是空格的話,這個函式將把下乙個可用 的ethx名稱賦給dev->name。

unsigned short eth_type_trans(struct sk_buff *skb,struct net_device *dev);

當乙太網介面接收到乙個資料報時,呼叫該函式設定skb->pkt_type。返回值是儲存早skb->protocol中的協議號。

#include

siocdevprivate

16個ioctl命令中的第乙個,每個驅動程式都能夠出於自身的考慮實現它。在sockios.h中定義了所有的網路ioctl命令。

#include

struct mii_if_info;

支援實現mii標準的裝置驅動程式的宣告和結構。

#include

struct ethtool_ops;

讓裝置可使用ethtool工具的宣告和結構。

LDD3讀書筆記(第3章 字元驅動)

include dev t dev t 是用來在核心裡代表裝置號的型別.int major dev t dev int minor dev t dev 從裝置編號中抽取主次編號的巨集.dev t mkdev unsigned int major,unsigned int minor 從主次編號來建立...

LDD3讀書筆記(第5章 記憶體分配)

include void kmalloc size t size,int flags 記憶體分配函式 後備快取記憶體 include kmem cache t kmem cache create const char name,size t size,size t offset,unsigned l...

LDD3 讀書筆記 之 第 3 章 字元驅動

本章介紹了下面符號和標頭檔案.struct file operations 和 struct file 中的成員的列表這裡不重複了.include dev t dev t 是用來在核心裡代表裝置號的型別.int major dev t dev int minor dev t dev 從裝置編號中抽取...