热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Linux3.4.2移植CS8900网卡驱动到优龙FS2410开发板

一、S3C2410和CS8900的硬件连接FS2410开发板的原理图我没有找到,但可看参考资料2,里面写的非常详细二、移植过程a)配置内核支持S3C2410c)修改driversn

一、S3C2410和CS8900的硬件连接

    FS2410开发板的原理图我没有找到,但可看参考资料2,里面写的非常详细

二、移植过程

a) 配置内核支持S3C2410

技术分享图片

技术分享图片

技术分享图片

选好Samsung S3C24XX SoCs后,会自动返回到上一级菜单(即前一张图),然后选择:

技术分享图片

技术分享图片

b) 配置内核支持CS89x0网卡

Device Drivers-->Network device support-->Ethernet driver support—>

技术分享图片

c) 修改drivers/net/ethenet/cirrus/cs89x0.c:

(1)在文件开头增加以下几行,它们在宏CONFIG_ARCH_S3C24XX被定义时起作用,表示作用于FS2410开发板

183 static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
184 #elif defined(CONFIG_ARCH_S3C24XX)
185 #include
186 #include
187 #define S3C24XX_PA_CS8900 0x19000000 /* 物理基地址 */
188 static unsigned int netcard_portlist[] __initdata = {0, 0}; /* 在下面进行设置 */
189 static unsigned int cs8900_irq_map[] = {IRQ_EINT9, 0, 0, 0}; /* 中断号*/
190 #else
191 #ifndef CONFIG_CS89x0_PLATFORM
192 static unsigned int netcard_portlist[] __used __initdata =

(2)修改入口函数cs89x0_probe

  以下使用宏CONFIG_ARCH_S3C24XX包裹起来的代码是新加的

311 struct net_device * __init cs89x0_probe(int unit)
312 {
313 struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
314 unsigned *port;
315 int err = 0;
316 int irq;
317 int io;
318 #if defined(CONFIG_ARCH_S3C24XX)
319 unsigned int oldval_bwscon; /* 用来保存BWSCON寄存器的值 */
320 unsigned int oldval_bankcon3; /* 用来保存S3C2410_BANKCON3寄存器的值 */
321 #endif
322 if (!dev)
323 return ERR_PTR(-ENODEV);
324
325 sprintf(dev->name, "eth%d", unit);
326 netdev_boot_setup_check(dev);
327 io = dev->base_addr;
328 irq = dev->irq;
329 #if defined(CONFIG_ARCH_S3C24XX)
330 // cs89x0_probe会被调用多次,我们只需要1次,根据netcard_portlist[0]的值忽略后面的调用
331 if (netcard_portlist[0])
332 return -ENODEV;
333 // 将CS8900A的物理地址转换为虚拟地址,0x300是CS8900A内部的IO空间的偏移地址
334 netcard_portlist[0] = (unsigned int)ioremap(S3C24XX_PA_CS8900, SZ_1M) + 0x300;
335 /* 设置默认MAC地址,
336 * MAC地址可以由CS8900A外接的EEPROM设定(有些单板没接EEPROM),
337 * 或者启动系统后使用ifconfig修改
338 */

339 dev->dev_addr[0] = 0x08;
340 dev->dev_addr[1] = 0x89;
341 dev->dev_addr[2] = 0x89;
342 dev->dev_addr[3] = 0x89;
343 dev->dev_addr[4] = 0x89;
344 dev->dev_addr[5] = 0x89;
345 /* 设置Bank3: 总线宽度为16, 使能nWAIT, 使能UB/LB。by www.100ask.net */
346 oldval_bwscon = *((volatile unsigned int *)S3C2410_BWSCON);
347 *((volatile unsigned int *)S3C2410_BWSCON) = (oldval_bwscon & ~(3<<12)) 348 | S3C2410_BWSCON_DW3_16 | S3C2410_BWSCON_WS3 | S3C2410_BWSCON_ST3;
349 /* 设置BANK3的时间参数, by www.100ask.net */
350 oldval_bankcon3 = *((volatile unsigned int *)S3C2410_BANKCON3);
351 *((volatile unsigned int *)S3C2410_BANKCON3) = 0x1f7c;
352 #endif
353 if (net_debug)
354 printk("cs89x0:cs89x0_probe(0x%x)\n", io);
355
356 if (io > 0x1ff) { /* Check a single specified location. */
357 err = cs89x0_probe1(dev, io, 0);
358 } else if (io != 0) { /* Don‘t probe at all. */
359 err = -ENXIO;
360 } else {
361 for (port = netcard_portlist; *port; port++) {
362 if (cs89x0_probe1(dev, *port, 0) == 0)
363 break;
364 dev->irq = irq;
365 }
366 if (!*port)
367 err = -ENODEV;
368 }
369 if (err)
370 goto out;
371 return dev;
372 out:
373 #if defined(CONFIG_ARCH_S3C24XX)
374 iounmap(netcard_portlist[0]);
375 netcard_portlist[0] = 0;
376
377 /* 恢复寄存器原来的值 */
378 *((volatile unsigned int *)S3C2410_BWSCON) = oldval_bwscon;
379 *((volatile unsigned int *)S3C2410_BANKCON3) = oldval_bankcon3;
380 #endif
381 free_netdev(dev);
382 printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n");
383 return ERR_PTR(err);
384 }
385 //#endif 多了一个
386 #endif

(3)修改模块入口函数init_module

以下使用宏CONFIG_ARCH_S3C24XX包裹起来的代码是新加的

1879 int __init init_module(void)
1880 {
1881 struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
1882 struct net_local *lp;
1883 int ret = 0;
1884 #if defined(CONFIG_ARCH_S3C24XX)
1885 unsigned int oldval_bwscon; /* 用来保存BWSCON寄存器的值 */
1886 unsigned int oldval_bankcon3; /* 用来保存S3C2410_BANKCON3寄存器的值 */
1887 #endif
1888 #if DEBUGGING
1889 net_debug = debug;
1890 #else
1891 debug = 0;
1892 #endif
1893 if (!dev)
1894 return -ENOMEM;
1895
1896 #if defined(CONFIG_ARCH_S3C24XX)
1897 // 将CS8900A的物理地址转换为虚拟地址,0x300是CS8900A内部的IO空间的偏移地址
1898 dev->base_addr = io = (unsigned int)ioremap(S3C24XX_PA_CS8900, SZ_1M) + 0x300;
1899 dev->irq = irq = cs8900_irq_map[0]; /* 中断号 */
1900
1901 /* 设置默认MAC地址,
1902 * MAC地址可以由CS8900A外接的EEPROM设定(有些单板没接EEPROM),
1903 * 或者启动系统后使用ifconfig修改
1904 */

1905 dev->dev_addr[0] = 0x08;
1906 dev->dev_addr[1] = 0x89;
1907 dev->dev_addr[2] = 0x89;
1908 dev->dev_addr[3] = 0x89;
1909 dev->dev_addr[4] = 0x89;
1910 dev->dev_addr[5] = 0x89;
1911
1912 /* 设置Bank3: 总线宽度为16, 使能nWAIT, 使能UB/LB。by www.100ask.net */
1913 oldval_bwscon = *((volatile unsigned int *)S3C2410_BWSCON);
1914 *((volatile unsigned int *)S3C2410_BWSCON) = (oldval_bwscon & ~(3<<12)) 1915 | S3C2410_BWSCON_DW3_16 | S3C2410_BWSCON_WS3 | S3C2410_BWSCON_ST3;
1916
1917 /* 设置BANK3的时间参数, by www.100ask.net */
1918 oldval_bankcon3 = *((volatile unsigned int *)S3C2410_BANKCON3);
1919 *((volatile unsigned int *)S3C2410_BANKCON3) = 0x1f7c;
1920 #else
1921 dev->irq = irq;
1922 dev->base_addr = io;
1923 #endif
… …
1971 out:
1972 #if defined(CONFIG_ARCH_S3C24XX)
1973 iounmap(dev->base_addr);
1974
1975 /* 恢复寄存器原来的值 */
1976 *((volatile unsigned int *)S3C2410_BWSCON) = oldval_bwscon;
1977 *((volatile unsigned int *)S3C2410_BANKCON3) = oldval_bankcon3;
1978 #endif
1979 free_netdev(dev);
1980 return ret;
1981 }

(4)修改模块退出函数cleanup_module

以下使用宏CONFIG_ARCH_S3C24XX包裹起来的代码是新加的

1983 void __exit
1984 cleanup_module(void)
1985 {
1986 unregister_netdev(dev_cs89x0);
1987 writeword(dev_cs89x0->base_addr, ADD_PORT, PP_ChipID);
1988 release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT);
1989 #if defined(CONFIG_ARCH_S3C24XX)
1990 iounmap(dev_cs89x0->base_addr);
1991 #endif
1992 free_netdev(dev_cs89x0);
1993 }
1994 #endif /* MODULE && !CONFIG_CS89x0_PLATFORM */
1995

(5)修改net_open  

1240 net_open(struct net_device *dev)
1241 {
1242 struct net_local *lp = netdev_priv(dev);
1243 int result = 0;
1244 int i;
1245 int ret;
1246 #if !defined(CONFIG_SH_HICOSH4) && !defined(CONFIG_ARCH_PNX010X) && !defined(CONFIG_ARCH_S3C24XX) /* uses irq#1, so this won‘t work */
1247 if (dev->irq <2) {
1248 /* Allow interrupts to be generated by the chip */
1249 /* Cirrus‘ release had this: */
1250 #if 0
1251 writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ );
1252 #endif
1253 /* And 2.3.47 had this: */
1254 writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);
... ...
1273 }
1274 else
1275 #endif
1276 {
1277 #if !defined(CS89x0_NONISA_IRQ) && !defined(CONFIG_CS89x0_PLATFORM)&& !defined(CONFIG_ARCH_S3C24XX)
1278 if (((1 <irq) & lp->irq_map) == 0) {
1279 printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
1280 dev->name, dev->irq, lp->irq_map);
1281 ret = -EAGAIN;
1282 goto bad_out;
1283 }
1284 #endif
1285 /* FIXME: Cirrus‘ release had this: */
1286 writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ );
1287 /* And 2.3.47 had this: */
1288 #if 0
1289 writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);
1290 #endif
1291 write_irq(dev, lp->chip_type, dev->irq);
1292 #if defined(CONFIG_ARCH_S3C24XX)
1293 ret = request_irq(dev->irq, &net_interrupt, IRQF_TRIGGER_RISING, dev->name, dev);
1294 #else
1295 ret = request_irq(dev->irq, net_interrupt, 0, dev->name, dev);
1296 #endif
1297 if (ret) {
1298 printk(KERN_ERR "cs89x0: request_irq(%d) failed\n", dev->irq);
1299 goto bad_out;
1300 }
1301 }
... ...
1358 /* check to make sure that they have the "right" hardware available */
1359 switch(lp->adapter_cnf & A_CNF_MEDIA_TYPE) {
1360 case A_CNF_MEDIA_10B_T: result = lp->adapter_cnf & A_CNF_10B_T; break;
1361 case A_CNF_MEDIA_AUI: result = lp->adapter_cnf & A_CNF_AUI; break;
1362 case A_CNF_MEDIA_10B_2: result = lp->adapter_cnf & A_CNF_10B_2; break;
1363 default: result = lp->adapter_cnf & (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2);
1364 }
1365 #if defined(CONFIG_ARCH_PNX010X) || defined(CONFIG_ARCH_S3C24XX)
1366 result = A_CNF_10B_T;
1367 #endif
1368 if (!result) {
1369 printk(KERN_ERR "%s: EEPROM is configured for unavailable media\n", dev->name);
1370 release_dma:
... ...
1478 }

(6)全局变量static int io 修改为static unsigned int io;

      原因请看参考资料1

最后,编译内核,执行make uImage。

三、参考资料

1、《嵌入式linux应用开发完全手册》韦东山

2、《FS2410中CS8900A IO模式驱动分析》杨志平

3、S3C2410 内存连接方法的深入研究

4、(转)CS8900A 驱动程序分析(国嵌)

5、AUI与BNC - BaiShi 在路上 - CSDN博客


推荐阅读
  • C#的Type对象的简单应用
    通过Type对象可以获取类中所有的公有成员直接贴代码:classMyClass{privatestringname;privateintid;publicstringcity;pu ... [详细]
  • linux filesystem_如何使用cgdb + qemu调试linux内核模块
    如何使用cgdbqemu调试linux内核模块前言Linux代码庞大而繁杂,光看代码会使人头晕目眩,如果能通过调试工具对其代码执行流程进行调试ÿ ... [详细]
  • Xib九宫格应用管理使用xib封装一个自定义view的步骤1新建一个继承UIView的自定义view,假设类名叫做(AppView)2新建一个AppView.xib文件来描述 ... [详细]
  • kepserver中文手册,kepserver使用教程,kepserver设置
    下面介绍一下KepServer模拟器的使用,以下示例使用服务器随附的Simulator驱动程序来演示创建、配置和运行项目的过程。Simulator驱动程序是基于内存的驱动程序,能为 ... [详细]
  • 简单动态字符串redis里面很多地方都用到了字符串,我们知道redis是一个键值对存储的非关系型数据库,那么所有的key都是用字符串存储的,还有字符串类型,这些都是用字符串存储的 ... [详细]
  • 例子如Table表有性别字段,1代表男2代表女、3代表中性、还有没填就代表未说明selectid,decode(sex,'1','男', ... [详细]
  • 下面是一个用openssl实现获取https网页内容的demo,整个流程比较简单,主要封装的API如下staticinthttps_init(http ... [详细]
  • 作业迁移
    背景:数据库服务器更换,1、数据库迁移(BACKUPRESTORE);2、数据库登录名用户迁移(注意孤立用户);3、作业迁移数据库迁移,备份数据库、拷贝备份文件到新服务器,还原数据 ... [详细]
  • rbac 4表 常规设计
    rbac4表常规设计设计模型:1、管理员表(users)Schema::create('users',function(Blueprint$table){$tabl ... [详细]
  • 开发笔记:Xunit测试使用个人小结
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Xunit测试使用个人小结相关的知识,希望对你有一定的参考价值。因工作中用到xunit测试,故总结下用法,以供个人参考使 ... [详细]
  • rtemsapi用户指南Elixir代表了相对较新的编程语言,面向更广泛的受众。它于2011年发布,此后一直在开发中。他的主要特征是取消功能范式 ... [详细]
  • 定义:定义两个数论函数\(f\)、\(g\)的Dirichlet卷积为:\[\left(f*g\right)\left(n\right)\sum_{d|n}f\left(d\rig ... [详细]
  • 目录结构如下:Nginx基础知识NginxHTTP服务器的特色及优点Nginx的主要企业功能Nginx作为web服务器的主要应用场景包括:Nginx的安装安装环境 ... [详细]
  • 接口自动化相关面试题
    你好,我是懂Java的测试最近辅导简历,有同学向我反馈,自学过接口自动化、没有落地接口自动化项目办?还有很多同学落地实践过自 ... [详细]
  • packagetest;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOE ... [详细]
author-avatar
伊子夕2010_593
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有