设为首页 收藏本站
查看: 1460|回复: 0

[经验分享] 27.Linux-DM9000C网卡移植(详解)

[复制链接]
YunVN网友  发表于 2017-11-17 21:32:15 |阅读模式
  上一节 我们学习了:  
  网卡驱动介绍以及制作虚拟网卡驱动: http://www.cnblogs.com/lifexy/p/7763352.html
  接下来本节,学习网卡芯片DM9000C,如何编写移植DM9000C网卡驱动程序。

  1.首先来看DM9000C原理图
  如下图所示:
   DSC0000.png
    (#:表示低电平有效)


  • SD0~15: 16位数据线,有CMD引脚决定访问类型
  • CMD:      命令线,当CMD为高,表示SD 传输的是数据,CMD为低表示传输的是地址
  • INT:         中断引脚,接在2440的GPF7脚上
  • IOR#:      读引脚,接在2440的nOE脚上
  • IOW#:     写引脚,接在2440的nWE脚上
  • CS#:       片选,放在2440的bank4的片选上面
  1.1其中2440手册的bank4地址区间如下图:
   DSC0001.png
  bank4的区间位于: 0X20000000~0X28000000,当我们访问这个区间的地址,内存控制器便会使能网卡DM9000C的使能脚,所以我们的DM9000C的io基地址=0X20000000
  其中DM9000C的CMD引脚接在bank4的LADDR2上面
  所以当访问的io基地址=0X2000 0000,表示读写的地址里的内容是DM9000C的地址
  访问的io基地址=0X2000 0100,表示读写的地址里的内容是DM9000C的数据
  
  1.2 DM9000C收发过程
  当DM9000C收到外部的数据后,会暂存到内部地址中,然后产生一个上升沿中断,等待2440读取数据
  当DM9000C将2440的数据转发出去后,也会产生一个上升沿中断给2440
  如下图所示,DM9000C的中断引脚位于pin34脚
   DSC0002.png
DSC0003.png

  接在2440的GPF7引脚上,使用的中断为EINT7
  
  接下来便来修改厂家提供的DM9000C源代码
  2.发现它的init_module()入口函数前有个条件编译
   DSC0004.png
  所以要注释掉 “#ifdef MODULE”“#endif”
  3.修改入口出口函数名,并修饰它们(修改函数名避免与内核的其它函数重名)
   DSC0005.png
DSC0006.png

DSC0007.png

  4.修改驱动的硬件相异性(设置基地址,寄存器,中断等)
  4.1先来找找代码在哪里初始化DM9000C硬件的
  进入dm9000c_init()
         -> dmfe_probe()
  其中dmfe_probe()函数如下:



struct net_device * __init dmfe_probe(void)
{
struct net_device *dev;
dev= alloc_etherdev(sizeof(struct board_info));          //分配一个net_device结构体
... ...
err = dmfe_probe1(dev);                                 //调用dmfe_probe1()函数
... ...
err = register_netdev(dev);                            //向内核注册net_device结构体
... ...
}
  显然dmfe_probe1()函数就是用来初始化DM9000C硬件和设置net_device结构体的成员用的
  4.2 进入dmfe_probe1()函数
  如下图,这个iobase 变量就是我们DM9000C的io基地址0x20000000
   DSC0008.png
  iobase的作用:
  如上图, 读一次DM9000C的VID低字节之前,需要先将地址赋为0x20000000,也就是将DM9000C的CMD置0,然后向0x20000000写入要读的DM9KS_VID_L地址值
  最后再将地址+4,也就是赋为0x20000100,将CMD置1,然后读出0x20000100的值,也就是DM9000C的VID低字节
  DM9000C的读写方式都是这样的,先将CMD置0,写入DM9000C的地址,然后再将CMD置1,来读写数据
  
  4.3所以在init函数中便重新设置iobase 变量,其中iobase是int型
   DSC0009.png
  并在exit出口函数中,添加iounmp()
   DSC00010.png
  4.4 继续进入dmfe_probe1()函数,往下看
  如下图所示,屏蔽红框里的代码,该代码用来核对版本,我们的DM9000C版本号不一样,所以要屏蔽
   DSC00011.png
  4.5 在init函数中,修改中断名,将irq改为IRQ_EINT7
   DSC00012.png
  4.6 修改中断
  当使用了register_netdev()注册了网卡驱动net_device后,在内核中使用ifconfig就会进入net_device->open成员函数申请中断,激活队列等
  所以我们要修改open成员函数的申请中断函数,将触发中断改为“IRQT_RISING”,上升沿触发
   DSC00013.png
  5.接下来便开始设置2440的存储控制寄存器
  设置2440的bank4的硬件位宽,时序,因为不同的硬件,涉及的数据收发都不同,
  5.1设置BWSCON总线宽度控制寄存器
  我们只设置BANK4的内容,所以只有下面3个(BANK0的位宽由OM[1:0] 硬件设置)
   DSC00014.png
  设置ST4=0,不使用UB/LB(UB/LB:表示高字节与低字节数据是否分开传输)
  设置WS4=0,其中WAIT引脚为PE4,而我们DM9000C没有引脚接入PE4,所以禁止
  设置DW4=0x01,我们的DM9000C的数据线为16位
  5.2设置BANKCON4控制寄存器
   DSC00015.png
   设置这些时序之前,首先来看DM9000C芯片手册时序图和2440的时序图
   DSC00016.png
  参考上图,得出BANKCON4 寄存器设置如下(HCLK=100MHZ,1个时钟等于10ns)
  设置Tacs=0,CS和CMD信号可以同时进行(CMD脚就是2440的地址引脚)
  设置Tcos=T1=0(CS片选使能后维持时间)
  设置Tacc=T2=0,要>=10ns(读写信号的访问维持时间)
  设置Tcoh=T4=1,要>=3ns(片选结束维持时间)
  设置Tcah=T8=0, CS和CMD信号可以同时结束(地址总线结束维持时间)
  代码如下图,在init入口函数中设置
   DSC00017.png
  与硬件相关的部分已经改好了,接下来开始编译
  6.编译测试
  编译之前,首先添加该驱动需要的内核头文件:



#include <asm/delay.h>
#include <asm/irq.h>
#include <linux/irq.h>
#include <asm/io.h>
#include <asm/arch-s3c2410/regs-mem.h>
  编译无误后,便开始测试DM9000C驱动程序:
  1) 把dm9dev9000c.c放到内核的drivers/net目录下,来替换原来内核的DM9000C
  2) 修改drivers/net/Makefile
  把

obj-$(CONFIG_DM9000) += dm9000.o

改为(如下图所示)

obj-$(CONFIG_DM9000) += dm9dev9000c.o
   DSC00018.png
  3) make uImage
  如下图,说明新的驱动已编译进内核
   DSC00019.png
  4) 使用新内核启动
  ifconfig eth0 192.168.2.107
  ping 192.168.2.1
  如下图,可以ping通,说明移植成功
   DSC00020.png

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-408038-1-1.html 上篇帖子: 转:【Linux】linux系统中find和whereis查找命令常用示例 下篇帖子: Linux系统学习之文件管理
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表