ARM-Linux驅動--DM9000網卡驅動分析(一)

2021-01-08 電子產品世界
硬體平臺:FL2440(s3c2440

內核版本:2.6.35

主機平臺:Ubuntu11.04

內核版本:2.6.39

原創作品,轉載請標明出處http://blog.csdn.net/yming0221/article/details/6609742

1、下圖是DM9000的引腳圖

2、這裡我們結合具體的開發板FL2440

下面是FL2440和DM9000的引腳連結圖

本人移植DM9000的時候將設備的資源定義放在了arch/arm/plat-s3c24xx/devs.c中,詳情點擊上一篇博文linux內核移植-移植2.6.35.4內核到s3c2440

下面是設備的資源定義

view plainprint?

static struct resource s3c_dm9000_resource[] = {

[0] = {

.start = S3C24XX_PA_DM9000,

.end = S3C24XX_PA_DM9000+ 0x3,

.flags = IORESOURCE_MEM

},

[1]={

.start = S3C24XX_PA_DM9000 + 0x4, //CMD pin is A2 0x20000304

.end = S3C24XX_PA_DM9000 + 0x4 + 0x7c, // 0x20000380

.flags = IORESOURCE_MEM

},

[2] = {

.start = IRQ_EINT7,

.end = IRQ_EINT7,

.flags = IORESOURCE_IRQ

},

};

這裡可以看到,DM9000網卡使用的地址空間資源在nGCS4地址區域,所以上圖的DM9000地址使能引腳連接nGCS4引腳。中斷使用的是EINT7外部中斷。

接著定義平臺數據和平臺設備,代碼如下:

view plainprint?

static struct dm9000_plat_data s3c_device_dm9000_platdata = {

.flags= DM9000_PLATF_16BITONLY,

};

struct platform_device s3c_device_dm9000 = {

.name= "dm9000", //設備名,該名稱與平臺設備驅動中的名稱一致

.id= 0,

.num_resources= ARRAY_SIZE(s3c_dm9000_resource),

.resource= s3c_dm9000_resource, //定義設備的資源

.dev= {

.platform_data = &s3c_device_dm9000_platdata, //定義平臺數據

}

};

最後導出函數符號,保存函數地址和名稱

view plainprint?

EXPORT_SYMBOL(s3c_device_dm9000);

3、設備啟動的初始化過程

view plainprint?

MACHINE_START(S3C2440, "SMDK2440")

.phys_io = S3C2410_PA_UART,

.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,

.boot_params = S3C2410_SDRAM_PA + 0x100,

.init_irq = s3c24xx_init_irq,

.map_io = smdk2440_map_io,

.init_machine = smdk2440_machine_init,//定義設備的初始化函數

.timer = &s3c24xx_timer,

MACHINE_END

而後會執行下面函數

view plainprint?

static void __init smdk2440_machine_init(void)

{

s3c24xx_fb_set_platdata(&smdk2440_fb_info);

s3c_i2c0_set_platdata(NULL);

s3c24xx_ts_set_platdata(&smdk2410_ts_cfg);

platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));

smdk_machine_init();

}

下面是具體的設備列表

view plainprint?

static struct platform_device *smdk2440_devices[] __initdata = {

&s3c_device_ohci,

&s3c_device_lcd,

&s3c_device_wdt,

&s3c_device_i2c0,

&s3c_device_iis,

&s3c_device_rtc,

&s3c24xx_uda134x,

&s3c_device_dm9000,

&s3c_device_adc,

&s3c_device_ts,

};

這樣系統啟動時,會給設備列表中的設備分配資源(地址資源和中斷資源等)。

4、信息傳輸中的信息封裝結構

4.1、sk_buff結構,定義在include/linux/skbuff.h中

view plainprint?

struct sk_buff {

struct sk_buff *next;

struct sk_buff *prev;

ktime_t tstamp;

struct sock *sk;

struct net_device *dev;

char cb[48] __aligned(8);

unsigned long _skb_refdst;

#ifdef CONFIG_XFRM

struct sec_path *sp;

#endif

unsigned int len,

data_len;

__u16 mac_len,

hdr_len;

union {

__wsum csum;

struct {

__u16 csum_start;

__u16 csum_offset;

};

};

__u32 priority;

kmemcheck_bitfield_begin(flags1);

__u8 local_df:1,

cloned:1,

ip_summed:2,

nohdr:1,

nfctinfo:3;

__u8 pkt_type:3,

fclone:2,

ipvs_property:1,

peeked:1,

nf_trace:1;

kmemcheck_bitfield_end(flags1);

__be16 protocol;

void (*destructor)(struct sk_buff *skb);

#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)

struct nf_conntrack *nfct;

struct sk_buff *nfct_reasm;

#endif

#ifdef CONFIG_BRIDGE_NETFILTER

struct nf_bridge_info *nf_bridge;

#endif

int skb_iif;

#ifdef CONFIG_NET_SCHED

__u16 tc_index;

#ifdef CONFIG_NET_CLS_ACT

__u16 tc_verd;

#endif

#endif

__u32 rxhash;

kmemcheck_bitfield_begin(flags2);

__u16 queue_mapping:16;

#ifdef CONFIG_IPV6_NDISC_NODETYPE

__u8 ndisc_nodetype:2,

deliver_no_wcard:1;

#else

__u8 deliver_no_wcard:1;

#endif

kmemcheck_bitfield_end(flags2);

#ifdef CONFIG_NET_DMA

dma_cookie_t dma_cookie;

#endif

#ifdef CONFIG_NETWORK_SECMARK

__u32 secmark;

#endif

union {

__u32 mark;

__u32 dropcount;

};

__u16 vlan_tci;

sk_buff_data_t transport_header;

sk_buff_data_t network_header;

sk_buff_data_t mac_header;

sk_buff_data_t tail;

sk_buff_data_t end;

unsigned char *head,

*data;

unsigned int truesize;

atomic_t users;

};

元素的含義如下(摘自內核,源碼,版本2.6.35.4)

*struct sk_buff - socket buffer

* @next: Next buffer inlist

* @prev: Previous buffer in list

* @sk: Socketwe are owned by

* @tstamp: Time we arrived

* @dev:Device we arrived on/are leaving by

* @transport_header:Transport layer header

* @network_header: Network layerheader

* @mac_header: Link layer header

*@_skb_refdst: destination entry (with norefcount bit)

* @sp:the security path, used for xfrm

* @cb: Control buffer. Freefor use by every layer. Put private vars here

* @len: Lengthof actual data

* @data_len: Data length

* @mac_len:Length of link layer header

* @hdr_len: writable headerlength of cloned skb

* @csum: Checksum (must includestart/offset pair)

* @csum_start: Offset from skb->headwhere checksumming should start

* @csum_offset: Offset fromcsum_start where checksum should be stored

* @local_df:allow local fragmentation

* @cloned: Head may be cloned(check refcnt to be sure)

* @nohdr: Payload reference only,must not modify header

* @pkt_type: Packet class

*@fclone: skbuff clone status

* @ip_summed: Driver fed us anIP checksum

* @priority: Packet queueing priority

*@users: User count - see {datagram,tcp}.c

* @protocol:Packet protocol from driver

* @truesize: Buffer size

*@head: Head of buffer

* @data: Data head pointer

*@tail: Tail pointer

* @end: End pointer

*@destructor: Destruct function

* @mark: Generic packetmark

* @nfct: Associated connection, if any

*@ipvs_property: skbuff is owned by ipvs

* @peeked: thispacket has been seen already, so stats have been

* done forit, dont do them again

* @nf_trace: netfilter packet traceflag

* @nfctinfo: Relationship of this skb to theconnection

* @nfct_reasm: netfilter conntrack re-assemblypointer

* @nf_bridge: Saved data about a bridged frame - seebr_netfilter.c

* @skb_iif: ifindex of device we arrivedon

* @rxhash: the packet hash computed on receive

*@queue_mapping: Queue mapping for multiqueue devices

*@tc_index: Traffic control index

* @tc_verd: traffic controlverdict

* @ndisc_nodetype: router type (from link layer)

*@dma_cookie: a cookie to one of several possible DMA operations

*done by skb DMA functions

* @secmark: security marking

*@vlan_tci: vlan tag control information

關於sk_buff的更多分析見另一篇轉載的博文http://blog.csdn.net/yming0221/article/details/6609734

4.2、net_device

關於net_device一個非常龐大的結構體,定義在/inlcude/linux/netdevice.h中

如下:

view plainprint?

struct net_device {

char name[IFNAMSIZ];

struct pm_qos_request_list *pm_qos_req;

struct hlist_node name_hlist;

char *ifalias;

unsigned long mem_end;

unsigned long mem_start;

unsigned long base_addr;

unsigned int irq;

unsigned char if_port;

unsigned char dma;

unsigned long state;

struct list_head dev_list;

struct list_head napi_list;

struct list_head unreg_list;

unsigned long features;

#define NETIF_F_SG 1

#define NETIF_F_IP_CSUM 2

#define NETIF_F_NO_CSUM 4

#define NETIF_F_HW_CSUM 8

#define NETIF_F_IPV6_CSUM 16

#define NETIF_F_HIGHDMA 32

#define NETIF_F_FRAGLIST 64

#define NETIF_F_HW_VLAN_TX 128

#define NETIF_F_HW_VLAN_RX 256

#define NETIF_F_HW_VLAN_FILTER 512

#define NETIF_F_VLAN_CHALLENGED 1024

#define NETIF_F_GSO 2048

#define NETIF_F_LLTX 4096

#define NETIF_F_NETNS_LOCAL 8192

#define NETIF_F_GRO 16384

#define NETIF_F_LRO 32768

#define NETIF_F_FCOE_CRC (1 << 24)

#define NETIF_F_SCTP_CSUM (1 << 25)

#define NETIF_F_FCOE_MTU (1 << 26)

#define NETIF_F_NTUPLE (1 << 27)

#define NETIF_F_RXHASH (1 << 28)

#define NETIF_F_GSO_SHIFT 16

#define NETIF_F_GSO_MASK 0x00ff0000

#define NETIF_F_TSO (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)

#define NETIF_F_UFO (SKB_GSO_UDP << NETIF_F_GSO_SHIFT)

#define NETIF_F_GSO_ROBUST (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)

#define NETIF_F_TSO_ECN (SKB_GSO_TCP_ECN << NETIF_F_GSO_SHIFT)

#define NETIF_F_TSO6 (SKB_GSO_TCPV6 << NETIF_F_GSO_SHIFT)

#define NETIF_F_FSO (SKB_GSO_FCOE << NETIF_F_GSO_SHIFT)

#define NETIF_F_GSO_SOFTWARE (NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6)

#define NETIF_F_GEN_CSUM (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)

#define NETIF_F_V4_CSUM (NETIF_F_GEN_CSUM | NETIF_F_IP_CSUM)

#define NETIF_F_V6_CSUM (NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM)

#define NETIF_F_ALL_CSUM (NETIF_F_V4_CSUM | NETIF_F_V6_CSUM)

#define NETIF_F_ONE_FOR_ALL (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \

NETIF_F_SG | NETIF_F_HIGHDMA | \

NETIF_F_FRAGLIST)

int ifindex;

int iflink;

struct net_device_stats stats;

#ifdef CONFIG_WIRELESS_EXT

const struct iw_handler_def * wireless_handlers;

struct iw_public_data * wireless_data;

#endif

const struct net_device_ops *netdev_ops;

const struct ethtool_ops *ethtool_ops;

const struct header_ops *header_ops;

unsigned int flags;

unsigned short gflags;

unsigned short priv_flags;

unsigned short padded;

unsigned char operstate;

unsigned char link_mode;

unsigned int mtu;

unsigned short type;

unsigned short hard_header_len;

unsigned short needed_headroom;

unsigned short needed_tailroom;

struct net_device *master;

unsigned char perm_addr[MAX_ADDR_LEN];

unsigned char addr_len;

unsigned short dev_id;

spinlock_t addr_list_lock;

struct netdev_hw_addr_list uc;

struct netdev_hw_addr_list mc;

int uc_promisc;

unsigned int promiscuity;

unsigned int allmulti;

#ifdef CONFIG_NET_DSA

void *dsa_ptr;

#endif

void *atalk_ptr;

void *ip_ptr;

void *dn_ptr;

void *ip6_ptr;

void *ec_ptr;

void *ax25_ptr;

struct wireless_dev *ieee80211_ptr;

unsigned long last_rx;

unsigned char *dev_addr;

struct netdev_hw_addr_list dev_addrs;

unsigned char broadcast[MAX_ADDR_LEN];

#ifdef CONFIG_RPS

struct kset *queues_kset;

struct netdev_rx_queue *_rx;

unsigned int num_rx_queues;

#endif

struct netdev_queue rx_queue;

struct netdev_queue *_tx ____cacheline_aligned_in_smp;

unsigned int num_tx_queues;

unsigned int real_num_tx_queues;

struct Qdisc *qdisc;

unsigned long tx_queue_len;

spinlock_t tx_global_lock;

unsigned long trans_start;

int watchdog_timeo;

struct timer_list watchdog_timer;

atomic_t refcnt ____cacheline_aligned_in_smp;

struct list_head todo_list;

struct hlist_node index_hlist;

struct list_head link_watch_list;

enum { NETREG_UNINITIALIZED=0,

NETREG_REGISTERED,

NETREG_UNREGISTERING,

NETREG_UNREGISTERED,

NETREG_RELEASED,

NETREG_DUMMY,

} reg_state:16;

enum {

RTNL_LINK_INITIALIZED,

RTNL_LINK_INITIALIZING,

} rtnl_link_state:16;

void (*destructor)(struct net_device *dev);

#ifdef CONFIG_NETPOLL

struct netpoll_info *npinfo;

#endif

#ifdef CONFIG_NET_NS

struct net *nd_net;

#endif

void *ml_priv;

struct net_bridge_port *br_port;

struct macvlan_port *macvlan_port;

struct garp_port *garp_port;

struct device dev;

const struct attribute_group *sysfs_groups[4];

const struct rtnl_link_ops *rtnl_link_ops;

unsigned long vlan_features;

#define GSO_MAX_SIZE 65536

unsigned int gso_max_size;

#ifdef CONFIG_DCB

const struct dcbnl_rtnl_ops *dcbnl_ops;

#endif

#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)

unsigned int fcoe_ddp_xid;

#endif

struct ethtool_rx_ntuple_list ethtool_ntuple_list;

};

我還沒有細細的分析這個結構體,驅動程序在probe函數中使用register_netdev()註冊該結構體指明的設備,將內核操作硬體的函數個內核聯繫起來。

相關焦點

  • ARM-Linux驅動--DM9000網卡驅動分析(二)
    硬體平臺:FL2440(s3c2440)內核版本:2.6.35主機平臺:Ubuntu 11.04內核版本:2.6.39原創作品,轉載請標明出處http://blog.csdn.net/yming0221/article/details/6612623下面開始分析具體的代碼,這裡由於使
  • ARM-Linux驅動--DM9000網卡驅動分析(四)
    硬體平臺:FL2440 (S3C2440)內核版本:2.6.35主機平臺:Ubuntu 11.04內核版本:2.6.39交叉編譯器:arm-linux-gcc 4.3.2原創作品,轉載請標明出處本文接上文ARM-Linux
  • U-Boot移植DM9000網卡
    根據書《嵌入式Linux應用開發完全手冊》移植網卡驅動,對於Jz2440開發板好像並不適用,Jz2440開發板使用的是DM9000網卡,已經不是書上講的CS8900網卡了。DM9000網卡與CS8900網卡接口方式不一樣,經過幾天的折騰,終於移植成功,現將筆記整理如下。
  • USB無線網卡的Linux驅動移植
    也就是說,整個移植過程要求USB無線網卡驅動必須是Realtek 8188SU,且工作環境是Linux2.6.12.7。Realtek公司對8188SU主晶片驅動提供的建議是PC機Fedora Linux 2.6.24測試通過。經測試,若直接將驅動使用Linux 2.6.12.7內核編譯,將出現大量錯誤。如何將驅動移植到Linux 2.6.12.7還需要進一步研究。
  • 詳解USB無線網卡的Linux驅動移植
    USB無線網卡是外部無線網絡系統提供的指定產品COMFAST CF150NS,其主晶片Realtek 8188SU的Linux內核版本要求是2.6.18~2.6.33。也就是說,整個移植過程要求USB無線網卡驅動必須是Realtek 8188SU,且工作環境是Linux2.6.12.7。
  • linux內核移植-移植2.6.35.4內核到s3c2440
    ,有人說是新的內核對arm平臺的支持不好,所以就降低了一下版本,這裡移植2.6.35.4內核一、準備工作1、下載 解壓內核從官網上下載linux-2.6.35的內核, ftp://ftp.kernel.org/pub/linux/kernel/v2.6/ ,文件不大,約85M。
  • arm驅動Linux內核開發之阻塞非阻塞IO輪詢操作
    《[arm驅動]Linux內核開發之阻塞非阻塞IO----輪詢操作》涉及內核驅動函數二個,內核結構體零個,分析了內核驅動函數二個;可參考的相關應用程式模板或內核驅動模板二個,可參考的相關應用程式模板或內核驅動一個一、概念:Poll是非阻塞IO----
  • 「正點原子Linux連載」第七十章Linux WIFI驅動實驗
    ,命令如下:cp arch/arm/boot/zImage /home/zuozhongkai/linux/tftpboot/ -f然後重啟開發板!!!70.1.4.5可以看出,RTL8189 SDIO WIFI驅動加載成功,同樣使用「ifconfig -a」命令查看一下是否有wlanX(X=0…n)網卡存在,如果有的話就說明RTL8189 SDIO WIFI驅動工作正常。
  • ARM-Linux驅動移植--RTC(實時時鐘)移植
    硬體平臺:FL2440本文引用地址:http://www.eepw.com.cn/article/201611/318866.htm內核版本:2.6.28主機平臺:Ubuntu 11.04內核版本:2.6.39首先修改內核源碼/arch/arm/mach-s3c2410/mach-smdk2410
  • WiFi驅動程序調試過程
    由於上一版採用AR9382插卡的方式,可以正常加載驅動程序,所以可以排除PCI-e總線的驅動問題;這一版的板載AR9582設計取自量產方案,可以保證設計準確性。 3. 看不到wlan0網卡的情況通常是由於WiFi未校準引起的,使用cat /proc/bus/pci/devices命令,可以看到AR9582的devid為0033,如果未校準devid應為abcd。 4.
  • 淺談分析Arm linux 內核移植及系統初始化的過程二
    具體註冊和註銷過程在下一節介紹。4.3. 處理器、設備4.4.調用驅動初始化函數初始化子系統。以此為入口,可以查詢所有的設備驅動。(void) linux/arch/arm/kernel/dma.cstatic int __init s3c2410_core_init(void) linux/arch/arm/mach-s3c2410/s3c2410.cpostcore_initcall(fn)static int ecard_bus_init(void) linux/arch/arm/kernel
  • ethtool 在 Linux 中的實現框架和應用
    對 Linux 網絡管理的重要性不言而喻,這些管理依賴於網絡工具,比如最常用的 ifconfig,route,ip,ethtool 等,其中 ethtool 提供了強大的網卡及網卡驅動管理能力,其具體的實現框架和網絡驅動程序及網絡硬體關係緊密,容易修改和擴展,能夠為 Linux 網絡開發人員和管理人員提供對網卡硬體,驅動程序和網絡協議棧的設置,查看以及及調試等功能。
  • 嵌入式Linux之我行——LED驅動在2440上的實例開發
    一、開發環境主機:VMWare--Fedora 9開發板:Mini2440--64MB Nand編譯器:arm-linux-gcc-4.3.2二、實現步驟
  • 「正點原子FPGA連載」第二十八章Linux蜂鳴器驅動實驗
    蜂鳴器驅動實驗上一章實驗中我們藉助gpio子系統編寫了LED燈驅動,領航者開發板上還有一個蜂鳴器,從軟體的角度考慮,蜂鳴器驅動和LED燈驅動其實是一摸一樣的,都是控制IO輸出高低電平。本章我們就來學習編寫蜂鳴器的Linux驅動,也算是對上一章講解的gpio子系統的鞏固。28.1有源蜂鳴器簡介蜂鳴器常用於計算機、印表機、報警器、電子玩具等電子產品中,常用的蜂鳴器有兩種:有源蜂鳴器和無源蜂鳴器,這裡的有「源」不是電源,而是震蕩源,有源蜂鳴器內部帶有震蕩源,所以有源蜂鳴器只要通電就會叫。無源蜂鳴器內部不帶震蕩源,直接用直流電是驅動不起來的,需要2K-5K的方波去驅動。
  • 網卡驅動怎麼更新 筆記本升級無線網卡驅動方法
    對於這種情況,我們可以通過更新網卡驅動來解決。下面百事網小編以自己聯想筆記本為演示,為大家介紹下筆記本升級無線網卡驅動方法。一、使用驅動精靈一鍵更新網卡驅動(推薦)1、首先在筆記本下載安裝新版的驅動精靈軟體,下載地址百度搜索「驅動精靈」即可找到下載地址。2、安裝完成後,打開驅動精靈軟體,之後軟體會自動識別到你的筆記本型號,然後我們在默認的基本狀態下,點擊下方的「立即檢測」,如下圖所示:
  • Linux USB總線驅動框架分析
    首先來看一個現象,插入USB設備後linux系統列印如下日誌:1.2 USB接入識別大致過程當識別出有USB設備插入後,linux內的USB總線驅動程序發出命令至該設備,與設備對話,並詢問設備信息(描述符),設備收到請求後,回復設備描述符給總線驅動程序。且總線驅動程序會為該設備分配一個地址,如上地址為2,當後期訪問某個USB設備時,均會通過這個地址編號,當新接入的USB設備被第一次訪問時,以地址0來訪問。
  • 驅動人生6網卡版一鍵安裝無線網卡驅動
    驅動人生6網卡版如何一鍵幫你安裝網卡驅動?不懂的話就跟著教程來吧。  測試硬體為戰神K610C-i5的硬體配置都新,因此Win7系統32位和64位都沒有自動識別網卡和顯卡等驅動。Win764位和32位裝好後,從設備管理器可以看到沒有無線網卡和有線網卡驅動  不管是64位還是32位Win7系統,驅動人生網卡版在安裝過程中,都會自動幫用戶把系統裡欠缺的無線網卡和有線網卡全部補齊
  • PWM在ARM Linux中的原理和蜂鳴器驅動實例開發
    由原理圖可以得知,蜂鳴器是通過GPB0 IO口使用PWM信號驅動工作的,而GPB0口是一個復用的IO口,要使用它得先把他設置成TOUT0 PWM輸出模式。將PWM蜂鳴器驅動代碼部署到內核中。#cp -f my2440_pwm.c /linux-2.6.30.4/drivers/char //把驅動源碼到內核驅動的字符設備下#gedit /linux-2.6.30.4/drivers/char/Kconfig //添加PWM蜂鳴器設備配置config MY2440_PWM_BEEPtristate"My2440