<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > ARM-Linux驅(qū)動--DM9000網(wǎng)卡驅(qū)動分析(一)

          ARM-Linux驅(qū)動--DM9000網(wǎng)卡驅(qū)動分析(一)

          作者: 時間:2016-11-20 來源:網(wǎng)絡(luò) 收藏
          硬件平臺:FL2440(s3c2440
          內(nèi)核版本:2.6.35
          主機平臺:Ubuntu11.04
          內(nèi)核版本:2.6.39
          原創(chuàng)作品,轉(zhuǎn)載請標明出處http://blog.csdn.net/yming0221/article/details/6609742
          1、下圖是DM9000的引腳圖
          2、這里我們結(jié)合具體的開發(fā)板FL2440
          下面是FL2440和DM9000的引腳鏈接圖
          本人移植DM9000的時候?qū)⒃O(shè)備的資源定義放在了arch/arm/plat-s3c24xx/devs.c中,詳情點擊上一篇博文linux內(nèi)核移植-移植2.6.35.4內(nèi)核到s3c2440
          下面是設(shè)備的資源定義
          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網(wǎng)卡使用的地址空間資源在nGCS4地址區(qū)域,所以上圖的DM9000地址使能引腳連接nGCS4引腳。中斷使用的是EINT7外部中斷。
          接著定義平臺數(shù)據(jù)和平臺設(shè)備,代碼如下:
          view plainprint?
          static struct dm9000_plat_data s3c_device_dm9000_platdata = {
          .flags= DM9000_PLATF_16BITONLY,
          };
          struct platform_device s3c_device_dm9000 = {
          .name= "dm9000", //設(shè)備名,該名稱與平臺設(shè)備驅(qū)動中的名稱一致
          .id= 0,
          .num_resources= ARRAY_SIZE(s3c_dm9000_resource),
          .resource= s3c_dm9000_resource, //定義設(shè)備的資源
          .dev= {
          .platform_data = &s3c_device_dm9000_platdata, //定義平臺數(shù)據(jù)
          }
          };
          最后導(dǎo)出函數(shù)符號,保存函數(shù)地址和名稱
          view plainprint?
          EXPORT_SYMBOL(s3c_device_dm9000);
          3、設(shè)備啟動的初始化過程
          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,//定義設(shè)備的初始化函數(shù)
          .timer = &s3c24xx_timer,
          MACHINE_END
          而后會執(zhí)行下面函數(shù)
          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();
          }
          下面是具體的設(shè)備列表
          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,
          };
          這樣系統(tǒng)啟動時,會給設(shè)備列表中的設(shè)備分配資源(地址資源和中斷資源等)。
          4、信息傳輸中的信息封裝結(jié)構(gòu)
          4.1、sk_buff結(jié)構(gòu),定義在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;
          };
          元素的含義如下(摘自內(nèi)核,源碼,版本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
          關(guān)于sk_buff的更多分析見另一篇轉(zhuǎn)載的博文http://blog.csdn.net/yming0221/article/details/6609734
          4.2、net_device
          關(guān)于net_device一個非常龐大的結(jié)構(gòu)體,定義在/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;
          };
          我還沒有細細的分析這個結(jié)構(gòu)體,驅(qū)動程序在probe函數(shù)中使用register_netdev()注冊該結(jié)構(gòu)體指明的設(shè)備,將內(nèi)核操作硬件的函數(shù)個內(nèi)核聯(lián)系起來。


          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();