S3C2440嵌入式Linux下网卡DM9000E移植

mini2440上移植DM9000E网卡的参考步骤如下:

一、看电路图

mini2440开发板上移植好Linux-2.6.29.1内核和根文件系统的基础上,进行网卡DM9000E的移植,因为手里面有韦东山写的《嵌入式Linux应用开发完全手册》一书,在书中找到了DM9000网卡移植部分,对照该书与友善光盘里面的原理图,移植之前先从看原理图开始。看了DM9000ES3C2440的电路图发现:

1DM9000E挂接到S3C2440总线

S3C2440通过总线来访问DM9000Emini2440访问DM9000E的物理地址的基址是BANK4,用到一条地址线ADDR2,对应DM9000ECMD引脚,,因为DM9000E的地址信号和数据信号复用,CMD引脚决定传输的是地址信号还是数据信号,于是地址线ADDR2的引脚状态决定了DM9000ES3C2440传输的是地址信号还是数据信号。

2、总线位宽16,用到nWAIT信号

3DM9000E收到完整的数据包,通过中断引脚通知S3C2440来接收数据包,与S3C2440相连的中断引脚为EINT7

二、网卡驱动程序修改

修改内核中网卡驱动程序时需要先结合所使用的内核,先查看当前内核是否支持该网卡,如果不支持需要查找支持该网卡的驱动程序进行修改。我用的是Linux-2.6.29.1内核,该内核已经对DM9000E具有很好的支持了,这在内核的Documentation/networking/dm9000.txt中有对内核中dm9000驱动程序详细地说明,其中如下部分说明Linux-2.6.29.1内核对DM9000E网卡的友好支持。

一些低版本的内核 ( 比如 linux-2.6.13 等 ) 对 DM9000E 不支持,可以 用 其它内核版本的 dm9000.c 驱动程序添加到内核中,进行修改和配置。由于这里使用的内核已经对 DM9000E 网卡具有很好的支持,只需简单的配置和修改即可。
1 、修改 DM9000 平台设备
修改 /arch/arm/plat-s3c24xx/common-smdk.c 文件

(1) 、添加要包含的头文件
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
#include
#endif
(2)、添加DM9000的平台设备结构
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
/*DM9000*/
static struct resource s3c_dm9k_resource[]={
[0] = {
.start = S3C2410_CS4, //ADDR2 = 0
.end = S3C2410_CS4 + 3,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = S3C2410_CS4 + 4, //ADDR2 = 1
.end = S3C2410_CS4 + 4 + 3,
.flags = IORESOURCE_MEM,
},
[2] = {
.start = IRQ_EINT7,
.end = IRQ_EINT7,
.flags = IORESOURCE_IRQ,
}
};
static struct dm9000_plat_data s3c_dm9k_platdata = {
.flags = DM9000_PLATF_16BITONLY,
};
static struct platform_device s3c_device_dm9k = {
.name = "dm9000",
.id = 0,
.num_resources = ARRAY_SIZE(s3c_dm9k_resource),
.resource = s3c_dm9k_resource,
.dev = {
.platform_data = &s3c_dm9k_platdata,
}
};
#endif

(3) 、将 DM9000 平台设备加入内核设备列表中
/* devices we initialise */
static struct platform_device __initdata *smdk_devs[] = {
&s3c_device_nand,
&smdk_led4,
&smdk_led5,
&smdk_led6,
&smdk_led7,
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
&s3c_device_dm9k,
#endif
};
2 、修改 drivers/net/dm9000.c
dm9000.c 中包含 dm9000_probe 函数,该函数完成 DM9000 设备的枚举, dm9000_probe 函数的介绍在《嵌入式 Linux 应用开发完全手册》一书中详细介绍。
(1) 、添加必要的头文件
#if defined(CONFIG_ARCH_S3C2410)
#include
#endif
在《嵌入式 Linux 应用开发完全手册》一书中上面的 #include 是 #include ,这使得我编译通不过,被我改成 #include 后编译成功,这是不同版本内核文件的程序所在文件的差别造成。
(2) 、在 dm9000_probe 中设置存储器使 BANK4 可用,设置默认 MAC 地址 ( 也可以在根文件系统启动脚本设置 ) ,添加的代码如下:
/*
* Search DM9000 board, allocate space and register it
*/
static int __devinit
dm9000_probe(struct platform_device *pdev)
{
#if defined(CONFIG_ARCH_S3C2410)
unsigned int oldval_bwscon; // 用来保存 BWSCON 寄存器的值
unsigned int oldval_bankcon4; // 用来保存 S3C2410_BANKCON4 寄存器的值
#endif
#if defined (CONFIG_ARCH_S3C2410)
// 设置 BANK4 :总线宽度为 16 ,使能 nWAIT
oldval_bwscon = *((volatile unsigned int *)S3C2410_BWSCON);
*((volatile unsigned int *)S3C2410_BWSCON) = (oldval_bwscon & ~(3<<16)) /
| S3C2410_BWSCON_DW4_16 | S3C2410_BWSCON_WS4 | S3C2410_BWSCON_ST4;
// 设置 BANK4 的时间参数
oldval_bankcon4 = *((volatile unsigned int *)S3C2410_BANKCON4);
*((volatile unsigned int *)S3C2410_BANKCON4) = 0x1f7c;
#endif
if (!is_valid_ether_addr(ndev->dev_addr))
dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please "
"set using ifconfig/n", ndev->name);
#if defined(CONFIG_ARCH_S3C2410)
printk("Now use the default MAC address:08:90:90:90:90:90/n");
ndev->dev_addr[0] = 0x08;
ndev->dev_addr[1] = 0x90;
ndev->dev_addr[2] = 0x90;
ndev->dev_addr[3] = 0x90;
ndev->dev_addr[4] = 0x90;
ndev->dev_addr[5] = 0x90;
#endif
out:
printk("%s:not found (%d)./n",CARDNAME,ret);
#if defined(CONFIG_ARCH_S3C2410)
*((volatile unsigned int *)S3C2410_BWSCON) = oldval_bwscon;
*((volatile unsigned int *)S3C2410_BANKCON4) = oldval_bankcon4;
#endif
(3) 、指定注册中断时的触发方式
dm9000_open(struct net_device *dev)
{
irqflags |= IRQF_SHARED;
#if defined (CONFIG_ARCH_S3C2410)
if(request_irq(dev->irq,&dm9000_interrupt,IRQF_SHARED|IRQF_TRIGGER_RISING,dev->name,dev))
#else
if(request_irq(dev->irq,&dm9000_interrupt,IRQF_SHARED,dev->name,dev))
#endif
//if (request_irq(dev->irq, &dm9000_interrupt, irqflags, dev->name, dev))
return -EAGAIN;
}
三、在内核中增加对网卡 DM9000 的配置
在内核目录下执行“ make menuconfig ”命令进行如下的配置:
Device Drivers--->
[*]Network device support--->
[*]Ethernet(10 or 100Mbit)--->
<*>DM9000 support
[*]Networking support--->
Networking options--->
<*>TCP/IP networking
<*>IP:kernel leel autoconfiguration
// 增加对 nfs 的支持
File systems--->
[*]Networking File Systems--->
<*>NFS client support
[*]NFS client support for NFS version 3
[*]NFS client support for the NFSv3 ACL protocol extension
[*]Boot file system on NFS
[*]NFS server support
四、修改根文件系统启动脚本 rcS
在根文件 etc/init.d/rcS 文件中添加如下:
echo "network interface"
/sbin/ifconfig lo 127.0.0.1
/sbin/ifconfig eth0 192.168.1.230 up
route add default gw 192.168.1.1
五、测试和修改
至此,将修改过的内核和根文件系统下载到 mini2440 开发板,启动时出现如下信息:
----------munt all----------------
network interface
dm9000 dm9000.0: WARNING: no IRQ resource flags set.
eth0: link up, 10Mbps, half-duplex, lpa 0x0021
***********************************************
****************Studying ARM*********************
Kernel version:linux-2.6.29.1
Student:Feng dong rui
Date:2009.07.15
***********************************************
Please press Enter to activate this console.
[MrFeng]#
1 、测试
Please press Enter to activate this console.
[MrFeng]#ifconfig -a
eth0 Link encap:Ethernet HWaddr 10:23:45:67:89:AB
inet addr:192.168.1.230 Bcast:192.168.1.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1506 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:101460 (99.0 KiB) TX bytes:0 (0.0 B)
Interrupt:51 Base address:0x8000
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:6 errors:0 dropped:0 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:504 (504.0 B) TX bytes:504 (504.0 B)
[MrFeng]#ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: seq="0" ttl="64" time="1".004 ms
64 bytes from 127.0.0.1: seq="1" ttl="64" time="0".518 ms
64 bytes from 127.0.0.1: seq="2" ttl="64" time="0".436 ms
^C
--- 127.0.0.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.436/0.652/1.004 ms
[MrFeng]#ping 192.168.1.103
PING 192.168.1.103 (192.168.1.103): 56 data bytes
64 bytes from 192.168.1.103: seq="0" ttl="64" time="2".098 ms
64 bytes from 192.168.1.103: seq="1" ttl="64" time="1".342 ms
64 bytes from 192.168.1.103: seq="2" ttl="64" time="0".823 ms
^C
--- 192.168.1.103 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.823/1.421/2.098 ms
// 挂载网络文件系统
[MrFeng]#mount -t nfs -o nolock 192.168.1.103:/opt/nfs /mnt
[MrFeng]#ls /mnt
pic.jpg
[MrFeng]#umount /mnt
[MrFeng]#ls /mnt
[MrFeng]#
注:在挂载网络文件系统时先要在 Linux 系统下设置共享目录才能在从开发板挂载该目录,这里已经在虚拟机下 Redhat9.0 系统中的 /opt 下设置了共享目录 nfs ,虚拟机的 ip 为 192.168.1.103 ,故通过 mount -t nfs -o nolock 192.168.1.103:/opt/nfs /mnt 命令挂载。
2 、曾经出现的问题
(1) 、 ping 不同局域网内其它主机, ping 自己也有时会出现如下问题:
[ ] (s3c_irq_demux_extint4t7+0x0/0xa8) from [ ] (asm_do_IRQ+0x
44/0x5c)
r4:c03c2350
[ ] (asm_do_IRQ+0x0/0x5c) from [ ] (__irq_svc+0x24/0xa0)
Exception stack(0xc2e2bd98 to 0xc2e2bde0)
bd80: 00000000 fb000000
bda0: 00000001 00000000 c03c2a18 00000033 40000013 00000080 00000033 00000000
bdc0: c39bfc80 c2e2be10 c2e2bdbc c2e2bde0 c007320c c0072748 60000013 ffffffff
r7:00000080 r6:00000010 r5:f4000000 r4:ffffffff
[ ] (setup_irq+0x0/0x248) from [ ] (request_irq+0xb0/0xcc)
[ ] (request_irq+0x0/0xcc) from [ ] (dm9000_open+0x16c/0x23c)
[ ] (dm9000_open+0x0/0x23c) from [ ] (dev_open+0xa8/0x10c)
[ ] (dev_open+0x0/0x10c) from [ ] (dev_change_flags+0x98/0x164
)
r5:00000000 r4:c382b800
[ ] (dev_change_flags+0x0/0x164) from [ ] (devinet_ioctl+0x2f0
/0x708)
r7:bed9ba88 r6:c39fdf00 r5:00000000 r4:ffffff9d
[ ] (devinet_ioctl+0x0/0x708) from [ ] (inet_ioctl+0xc0/0xf4)
[ ] (inet_ioctl+0x0/0xf4) from [ ] (sock_ioctl+0x1e4/0x244)
[ ] (sock_ioctl+0x0/0x244) from [ ] (vfs_ioctl+0x3c/0x84)
r7:00000003 r6:00008914 r5:ffffffe7 r4:c2d1a420
[ ] (vfs_ioctl+0x0/0x84) from [ ] (do_vfs_ioctl+0x284/0x2a4)
r6:00000000 r5:bed9ba88 r4:c2d1a420
[ ] (do_vfs_ioctl+0x0/0x2a4) from [ ] (sys_ioctl+0x40/0x5c)
r7:00000036 r6:00008914 r5:fffffff7 r4:c2d1a420
[ ] (sys_ioctl+0x0/0x5c) from [ ] (ret_fast_syscall+0x0/0x2c)
r6:00000000 r5:00159dec r4:00159d5c
出现这个问题的原因是我没将中断的触发方式按照默认的,没有改成上面修改的。
(2) 、挂载不了网络文件系统
可能的原因:检查内核的配置中是否选中对 NFS 的支持, Linux 主机是否能连通局域网并设置了共享目录,硬件的链接是否良好。还有就是 Linux 主机的防火墙是否关闭, nfs 服务是否已经开启。
六、参考资料
在学习的过程中,参考了韦东山写的《嵌入式 Linux 应用开发完全手册》一书,该书我觉得虽然没有把很多东西讲得很详细,嵌入式 Linux 的书也不可能在一本书上讲得详细,但我每想做什么就不自觉的翻阅它,对我来说非常具有参考价值。另外就是网上的一些热心网友的博客、帖子上的内容给了我很多参考,结合“百家之长”解决问题,网上的资料很多,不一一列举。
以上为复制。
今天步骤
1.按照韦东山写的《嵌入式Linux应用开发完全手册》,并把miniarm dm9000.c #if defined (CONFIG_ARCH_S3C2410)
#endif  宏里的直接复制到 linux 2.6.34 dm9000.c中。开始图省事,把dm9000.c dm9000.h,直接替换,并把include/linux/netdevice.h 也替换,并不成功。还是按照韦东山自己修改,成功。
2.修改文件系统 /etc/init.d/rcS 
3.mount 成功
4.试hello。ko驱动。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值