硬件平臺(tái):FL2440(s3c2440)內(nèi)核版本:2.6.35
主機(jī)平臺(tái):Ubuntu11.04
內(nèi)核版本:2.6.39
原創(chuàng)作品,轉(zhuǎn)載請(qǐng)標(biāo)明出處http://blog.csdn.net/yming0221/article/details/6609742
1、下圖是DM9000的引腳圖
2、這里我們結(jié)合具體的開(kāi)發(fā)板FL2440
下面是FL2440和DM9000的引腳鏈接圖
本人移植DM9000的時(shí)候?qū)⒃O(shè)備的資源定義放在了arch/arm/plat-s3c24xx/devs.c中,詳情點(diǎn)擊上一篇博文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外部中斷。
接著定義平臺(tái)數(shù)據(jù)和平臺(tái)設(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è)備名,該名稱(chēng)與平臺(tái)設(shè)備驅(qū)動(dòng)中的名稱(chēng)一致
.id= 0,
.num_resources= ARRAY_SIZE(s3c_dm9000_resource),
.resource= s3c_dm9000_resource, //定義設(shè)備的資源
.dev= {
.platform_data = &s3c_device_dm9000_platdata, //定義平臺(tái)數(shù)據(jù)
}
};
最后導(dǎo)出函數(shù)符號(hào),保存函數(shù)地址和名稱(chēng)
view plainprint?
EXPORT_SYMBOL(s3c_device_dm9000);
3、設(shè)備啟動(dòng)的初始化過(guò)程
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
而后會(huì)執(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)啟動(dòng)時(shí),會(huì)給設(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;
};
元素的含義如下(摘自?xún)?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的更多分析見(jiàn)另一篇轉(zhuǎn)載的博文http://blog.csdn.net/yming0221/article/details/6609734
4.2、net_device
關(guān)于net_device一個(gè)非常龐大的結(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;
};
我還沒(méi)有細(xì)細(xì)的分析這個(gè)結(jié)構(gòu)體,驅(qū)動(dòng)程序在probe函數(shù)中使用register_netdev()注冊(cè)該結(jié)構(gòu)體指明的設(shè)備,將內(nèi)核操作硬件的函數(shù)個(gè)內(nèi)核聯(lián)系起來(lái)。
評(píng)論