dm9000的驱动分析

m9000_init
 platform_driver_register();
 db);
 db);
 );
  ;
 id_val ;
 id_val ;
 /* 获取芯片型号 */
 id_val = ior(db, DM9000_CHIPR);
 ether_setup(ndev);
 /*设置操作方法*/
 ndev->netdev_ops  = &dm9000_netdev_ops;
 /*注册网络设备*/
 register_netdev(ndev);   //register_chrdev

cs8900a网卡驱动分析

);
 /*识别芯片*/
 /*操作方法的设置*/
 dev->netdev_ops = &net_ops;
 /*注册网络设备*/
 register_netdev(dev);

static const struct net_device_ops dm9000_netdev_ops = {
 .ndo_open    = dm9000_open,   //必须的
 .ndo_stop    = dm9000_stop,   //必须的
 .ndo_start_xmit   = dm9000_start_xmit, //必须的
 .ndo_tx_timeout   = dm9000_timeout,  //必须的
 .ndo_set_multicast_list = dm9000_hash_table,
 .ndo_do_ioctl   = dm9000_ioctl,
 .ndo_change_mtu   = eth_change_mtu,
 .ndo_validate_addr  = eth_validate_addr,
 .ndo_set_mac_address = eth_mac_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
 .ndo_poll_controller = dm9000_poll_controller,
#endif
};

网卡驱动的数据接收发送流程?

初始化设备

dm9000_open();
    writeb(NCR_RST, db);
  /* dm9000的初始化,芯片厂商会支持 */
  dm9000_init_dm9000(dev);
  
  /* 启动发送队列 */
  netif_start_queue(dev);
}

数据接收流程

dm9000_interrupt())   );  );
   (db->inblk)(db->io_data, rdptr, RxLen);  //dm9000_inblk_16bit   //读真正的有效数据(MAC头,TCP头,IP头,网络数据)
   dev->stats.rx_bytes += RxLen;
   /* Pass to upper layer,去掉MAC头 */
   skb->protocol = eth_type_trans(skb, dev);
   /* 将数据上报到上层 */
   netif_rx(skb);
   dev->stats.rx_packets++;

数据发送流程

sk_buff
dm9000_start_xmit
 );
  )
    dm9000_send_packet(dev, db);
     /*启动发送:数据发送完成,产生中断*/
     iow(dm, DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */

netif_wake_queue(dev);
 /* Re-enable interrupt mask */
 iow(db, DM9000_IMR, db->imr_all);
 /* Restore previous register address */
 writeb(reg_save, db->io_addr);  //恢复为自动增加

怎么写网卡驱动

1.cs89x0.c

1.1 分配一个net_device结构体

alloc_etherdev

1.2 设置

    dev->open       = net_open;
    dev->stop       = net_close;
    dev->tx_timeout     = net_timeout;
    dev->watchdog_timeo = HZ;
    dev->hard_start_xmit    = net_send_packet;
    dev->get_stats      = net_get_stats;
    dev->set_multicast_list = set_multicast_list;
    dev->set_mac_address    = set_mac_address;

1.3 注册

register_netdev

2. DM9000.c

2.1 分配一个net_device结构体
    ndev = alloc_etherdev(sizeof (struct board_info));
2.2 设置

    ether_setup(ndev);
    ndev->open       = &dm9000_open;
    ndev->hard_start_xmit    = &dm9000_start_xmit;
    ndev->tx_timeout         = &dm9000_timeout;
    ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
    ndev->stop       = &dm9000_stop;
    ndev->get_stats      = &dm9000_get_stats;
    ndev->set_multicast_list = &dm9000_hash_table;

2.3 注册
    ret = register_netdev(ndev);

任何设备的核心都是收发数据

1. 发数据:
   上层要发送数据时,构造一个sk_buff,然后调用net_device的hard_start_xmit来发送

2. 收数据:
   网卡收到数据后,发生中断
   在中断服务程序里:
   从硬件上读出数据,然后构造一个sk_buff,上报:
a. 分配一个sk_buff结构体:
    dev_alloc_skb
b. 使用硬件上得到数据填充这个结构体
c. 上报:netif_rx

测试方法

1. 编译/安装驱动 farsight_net_1.c

   ifconfig fs_net0 up
   ifconfig fs_net0 ...
   ping ... 成功,证明ping自己的话,不经过硬件
   ping ... 多次调用fsnet_hard_start_tx 
   PING ... (...) data bytes
   fsnet_hard_start_tx 
   fsnet_hard_start_tx    
   再次ifconfig发现fs_net0的rx/tx都是0

2. 编译/安装驱动 farsight_net_2.c: 添加统计信息

3. 编译/安装驱动 farsight_net_3.c: 设MAC地址
   ifconfig fs_net0
   ifconfig         可以看到MAC地址

4. 编译/安装驱动 farsight_net_4.c: 构造ping的返回包
   ifconfig fs_net0 up
   ifconfig fs_net0 192.188.1.1
   ping 192.188.1.2                成功

怎么移植网卡驱动

网卡基本上都是内存接口(ram-like)
    1. 根据原理图确定访问地址, 在驱动里修改相应项
    2. 为了能通过这些地址访问网卡,对于2410还要设置memory controller
   比如设置位宽、时间参数
    3. 根据原理图确定中断号, 在驱动里修改相应项(包括中断号、中断触发方式(高/低有效))

@成鹏致远

(blogs:http://lcw.cnblogs.com)

(emailwwwlllll@126.com)

【Linux高级驱动】如何分析并移植网卡驱动的更多相关文章

  1. 26.Linux-网卡驱动介绍以及制作虚拟网卡驱动(详解)

    1.描述 网卡的驱动其实很简单,它还是与硬件相关,主要是负责收发网络的数据包,它将上层协议传递下来的数据包以特定的媒介访问控制方式进行发送, 并将接收到的数据包传递给上层协议. 网卡设备与字符设备和块 ...

  2. X-010 FriendlyARM tiny4412 uboot移植之移植网卡驱动TFTP用起来

    <<<<<<<<<<<<<<<<<<<<<<<<< ...

  3. tiny4412学习(三)之移植linux-4.x驱动(1)支持网卡驱动【转】

    本文转载自:http://blog.csdn.net/fengyuwuzu0519/article/details/74160686 一.思路 上一节我们通过DNW将内核.文件系统.设备树文件烧入到内 ...

  4. 二十、网卡框架分析、虚拟网卡驱动和DM9621驱动分析

    一.网络设备驱动的结构 网卡设备不同于字符设备和块设备, 网络设备并不对应于/dev目录下的文件,它存放在/sys/class/net目录下. Linux系统对网络设备驱动定义了四个层次: 1. 网络 ...

  5. linux 内核启动流程分析,移植

    分析 linux-2.6.22.6 内核启动流程 移植 linux-3.4.2 到 JZ2440 开发板 Linux内核源码百度云链接: https://pan.baidu.com/s/1m1ymGl ...

  6. Linux高级网络设置——将多个网卡设置成一个网卡

    Linux下可以设置网卡模式 模式0:负载均衡 模式1:主备模式,不提高网络带宽 模式3:多网卡同时发送相同的数据 准备实验环境: Redhat 6.4 企业版64位,最小化安装. 给虚拟机添加网卡 ...

  7. Linux内核循环链表经典分析和移植

    为什么说这个链表做的经典呢,哥哥我从Linux内核里边儿扣出来的,要么怎么说内核不是一般人能写的,这代码太TM优美了! 这里有一篇参考文章:http://isis.poly.edu/kulesh/st ...

  8. AM335x(TQ335x)学习笔记——Nand&&网卡驱动移植

    移植完成声卡驱动之后本想再接再励,移植网卡驱动,但没想到的是TI维护的内核太健壮,移植网卡驱动跟之前移植按键驱动一样简单,Nand驱动也是如此,于是,本人将Nand和网卡放在同一篇文章中介绍.介绍之前 ...

  9. Linux网卡驱动框架及制作虚拟网卡

    1.概述 网卡驱动与硬件相关,主要负责收发网络的数据包,将上层协议传递下来的数据包以特定的媒介访问控制方式进行发送,并将接收到的数据包传递给上层协议. 网卡设备与字符设备,块设备不同,网络设备驱动程序 ...

随机推荐

  1. 求链表的倒数第m个元素

    法一: 首先遍历一遍单链表,求出整个单链表的长度n,然后将倒数第m个,转换为正数第n-m+1个,接下去遍历一次就可以得到结果. 不过这种方法需要对链表进行两次遍历,第一次遍历用于求解单链表的长度,第二 ...

  2. P3917 异或序列

    P3917 异或序列暴力前缀异或枚举每一个区间,再求和,60分.正解:按每一位来做对于区间[l,r],如果它对答案有贡献,区间中1的个数一定是奇数,可以按每一位取(1<<i)的前缀和,q[ ...

  3. 004.Docker镜像管理

    一 镜像基本操作 镜像是一个包含程序运行必要依赖环境和代码的只读文件,其本质是磁盘上一系列文件的集合.它采用分层的文件系统,将每一次改变以读写层的形式增加到原来的只读文件上.镜像是容器运行的基石. 1 ...

  4. JavaNIO快速入门

    NIO是Jdk中非常重要的一个组成部分,基于它的Netty开源框架可以很方便的开发高性能.高可靠性的网络服务器和客户端程序.本文将就其核心基础类型Channel, Buffer, Selector进行 ...

  5. Visual Studio 2017 版本 15.5.5

    Visual Studio 2017 版本 15.5.5 已修复的问题 (1)Xamarin 应用会引发“Cannot access a disposed object. Object name: ' ...

  6. BZOJ.5404.party(树链剖分 bitset Hall定理)

    题目链接 只有指向父节点的单向道路,所以c个人肯定在LCA处汇合.那么就成了有c条到LCA的路径,求最大的x,满足能从c条路径中各选出x个数,且它们不同. 先要维护一条路径的数的种类数,可以树剖+每条 ...

  7. php date_default_timezone_set()设置时区

    <?php echo function_exists(date_default_timezone_set)."<br>";//在这他总是返回1,这函数是判断这里面 ...

  8. [NOIp2012提高组]同余方程

    OJ题号: 洛谷1082 思路: 逆元模板. #include<cstdio> #include<cctype> inline int getint() { char ch; ...

  9. Linux 下 make 命令 及 make 笔记

    Linux 下 make 命令是系统管理员和程序员用的最频繁的命令之一.管理员用它通过命令行来编译和安装很多开源的工具,程序员用它来管理他们大型复杂的项目编译问题.本文我们将用一些实例来讨论 make ...

  10. CocosCreator小栗子

    主要是了解了场景切换的API,见下: 开始场景和结束场景内,按钮挂相同的Btn脚本,主要是切换到场景2中: Btn脚本如下, onLoad:function() { this.node.on('mou ...