linux网卡驱动移植
2016-05-30 21:30
459 查看
这里重要的是物理层PHY receiver,MAC(media access control)层,这里与软件中的协议栈不同,在硬件上MAC是PHY的下一层。DM9000A将MAC和PHY做到一起,也可以像IIS设备那样,SOC内有IIS的控制器,而声卡UDA1341放在片外。网卡当然也有这种设计,它是把PHY的下层MAC放入SOC内,片外的是PHY,当然我暂时还没见过这种的。DM9000A的输入是并行的总线,可以和CPU直接IO。而IIS那种需要通过:CPU CORE BUS->I2S控制器->外设。通过对比,应该了解DM9000A怎样进行IO了吧。其中PHY receiver中的AUTO-MDIX控制网卡的自适应,也就是说它能自动检测连接的是什么速度的网络,切换100,10。如果双方都是自适应的,那就依据误码率来选择。图中的EEPROM当然存放的是MAC的地址,那么驱动从哪里得到MAC地址的?1)你手工设置的,然后他给你写入到EEPROM里2)要么就是EEPROM里面应该好了。图中的MII是一种称为媒体独立接口的东西,是为了和PHY连接而设计的。
再来看一下上边这个DM9000A的原理图,它的CMD引脚接在CPU的ADDR2上。这里的地址线和数据线是进行复用的。当CMD为0时,SD0~SD15传的是地址,当CMD为1时,SD0~SD15传的是数据。
DM9000A的驱动作为platform_driver注册到内核中,根据Linux设备驱动模型,还应该有一个platform_device,但是源码里没有这个,这就需要我们自己来添加了,在arch/arm/plat-s3c24xx/devs.c中,添加:
#include <linux/dm9000.h> /* DM9000 Net Card */ 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 .end = S3C24XX_PA_DM9000 + 0x4 + 0x3, .flags = IORESOURCE_MEM }, [2] = { .start = IRQ_EINT7, .end = IRQ_EINT7, .flags = IORESOURCE_IRQ }, }; static struct dm9000_plat_data s3c_device_dm9000_platdata = { .flags= DM9000_PLATF_16BITONLY, }; struct platform_device s3c_device_dm9000 = { .name= "dm9000", .id= 0, .num_resources= ARRAY_SIZE(s3c_dm9000_resource), .resource= s3c_dm9000_resource, .dev= { .platform_data = &s3c_device_dm9000_platdata, } }; EXPORT_SYMBOL(s3c_device_dm9000);
注意这里第一个IO内存资源的范围是从S3C24XX_PA_DM9000~ S3C24XX_PA_DM9000+ 0x3,第二个IO内存资源的范围是从S3C24XX_PA_DM9000 + 0x4~ S3C24XX_PA_DM9000 + 0x4 + 0x3。这相当于两个32位的寄存器。一个是地址寄存器,一个是数据寄存器。向地址寄存器中写入0x1相当于选中了offset为1的NCR。向数据寄存器中写入数据他会自动写入TX RAM中。什么是TX RAM在DM9000A的驱动框架源码分析文档中已经解释了,这里就不再赘述。在这个文件中添加了平台设备的资源和平台设备。那么这个平台设备又是什么时候注册进内核的呢?我们继续往下看。在设备列表添加对DM9000A设备的支持,在arch/arm/mach-s3c2440/mach-smdk2440.c文件中,添加红色这一行:
static struct platform_device *smdk2440_devices[] __initdata = { &s3c_device_usb, &s3c_device_lcd, &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_iis, &s3c_device_rtc, &s3c_device_dm9000, };
那么这些platform_device是什么时候注册的呢,看这个文件下边的代码,很明了了,在系统初始化的时候会注册这个设备列表中的每一个设备。
static void __init smdk2440_machine_init(void) { s3c24xx_fb_set_platdata(&smdk2440_fb_info); s3c_i2c0_set_platdata(NULL); platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices)); smdk_machine_init(); } MACHINE_START(S3C2440, "SMDK2440") /* Maintainer: Ben Dooks <ben@fluff.org> */ .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, .timer = &s3c24xx_timer, MACHINE_END
然后修改arch/arm/plat-s3c24xx/include/mach/devs.h,添加:
extern struct platform_device s3c_device_dm9000;
修改arch/arm/mach-s3c2410/include/mach/map.h 文件
/* DM9000 */
#define S3C24XX_PA_DM9000 0x20000000
#define S3C24XX_VA_DM9000 0xE0000000
这里设定了网卡的物理地址和虚拟地址,在arch/arm/mach-s3c2410/mach-smdk2410.c中进行静态映射,在static
struct platform_device *smdk2410_devices[] __initdata中添加
view
plainprint?
static struct map_desc smdk2410_iodesc[] __initdata = {
[0] = {
.virtual = (unsigned long)S3C24XX_VA_DM9000,
.pfn = __phys_to_pfn(S3C24XX_PA_DM9000),
.length = SZ_1M,
.type = MT_DEVICE,
},
};
这样在程序中访问S3C24XX_PA_DM9000,S3C24XX_PA_DM9000
+ 0x4对应的物理地址,就直接转换到相应的虚拟地址了。至此DM9000A平台设备的添加和IO地址的静态映射完成。然后就是修改DM9000A中的MAC地址等了。
修改drivers/net/dm9000.c 文件,增加3行:
view plainprint?
#include <mach/regs-gpio.h>
#include <mach/irqs.h>
#include <mach/hardware.h>
修改dm9000_probe函数,添加:
unsigned char mac_addr[]={0x00,0x11,0x22,0x33,0x44,0x55}; static void *bwscon; static void *gpfcon; static void *extint0; static void *intmsk; #define BWSCON (0x48000000) #define GPFCON (0x56000050) #define EXTINT0 (0x56000088) #define INTMSK (0x4A000008) bwscon=ioremap_nocache(BWSCON,0x0000004); gpfcon=ioremap_nocache(GPFCON,0x0000004); extint0=ioremap_nocache(EXTINT0,0x0000004); intmsk=ioremap_nocache(INTMSK,0x0000004); writel(readl(bwscon)|0xc0000,bwscon); writel( (readl(gpfcon) & ~(0x3 << 14)) | (0x2 << 14), gpfcon); writel( readl(gpfcon) | (0x1 << 7), gpfcon); // Disable pull-up writel( (readl(extint0) & ~(0xf << 28)) | (0x4 << 28), extint0); //rising edge writel( (readl(intmsk)) & ~0x80, intmsk);
这里主要设置了总线宽度&等待寄存器,设置相应的GPIO引脚为EXINT7,中断为上升沿触发。
在这个函数的最后需要修改:
view plainprint?
if (!is_valid_ether_addr(ndev->dev_addr)) {
/* try reading from mac */
mac_src = "chip";
for (i = 0; i < 6; i++)
//ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
ndev->dev_addr[i] = mac_addr[i];
}
在文件系统中添加网络配置文件,使系统在开机过程中自动完成对网卡的配置
1)在文件系统/etc/net.conf文件中添加内容
view plainprint?
IPADDR=192.168.0.105
NETMASK=255.255.255.0
GATEWAY=192.168.0.1
MAC=00:11:22:33:44:55
2)在文件系统/sbin/目录下新建一个可执行的脚本文件net_config,注意文件的权限(可执行)
view plainprint?
#!/bin/sh
echo Try to bring eth0 interface up ...>/dev/s3c2410_serial0
if [ -f /etc/net.conf ] ; then
source /etc/net.conf
ifconfig eth0 down
ifconfig eth0 hw ether $MAC
echo ifconfig eth0 hw ether $MAC >/dev/s3c2410_serial0
ifconfig eth0 $IPADDR netmask $NETMASK up
echo ifconfig eth0 $IPADDR netmask $NETMASK up >/dev/s3c2410_serial0
route add default gw $GATEWAY
echo add default gw $GATEWAY >/dev/s3c2410_serial0
else
ifconfig eth0 hw ether 00:11:22:33:44:55
ifconfig eth0 192.168.1.105 netmask 255.255.255.0 up
route add default gw 192.168.0.1
echo ifconfig eth0 hw ether 00:11:22:33:44:55 >/dev/s3c2410_serial0
echo ifconfig eth0 192.168.0.105 netmask 255.255.255.0 up >/dev/s3c2410_serial0
echo route add default gw 192.168.0.1 >/dev/s3c2410_serial0
fi
echo Done > /dev/s3c2410_serial0
3)在文件系统/etc/init.d/rcS文件中添加网络配置语句
view plainprint?
/sbin/ifconfig lo 127.0.0.1 #设置本地回环设备的IP地址
net_config& #执行上面的net_config文件对网卡进行设置
在文件系统中添加完上述网卡配置信息后重新编译文件系统下载到开发板,系统上电启动后就会对网卡自动配置,并执行#ifconfig命令可以看到网卡的配置信息
测试与主机的通信,开发板的IP地址可以在/etc/net.conf中修改
s5pv210网卡驱动移植:http://www.openedv.com/thread-46879-1-1.html
实际上给内核移植DM9000驱动时,修改的代码不超过到5行,但是为什么这样改,一定要弄明白。 首先看改的代码: 因为板子上DM9000接在BANK1位置,所以在Map.h (arch\arm\mach-s5pv210\include\mach) 中添加S5PV210_PA_SROM_BANK1的地址定义
......
#define S5PV210_PA_SROM_BANK5 0xA8000000 #define S5PV210_PA_SROM_BANK1 0x88000000 ...... 因为u-boot中已经对DM9000已经初始化了,所以要屏蔽掉Mach-smdkv210.c (arch\arm\mach-s5pv210) 中的初始化代码:
[C] 纯文本查看 复制代码
?
[C] 纯文本查看 复制代码
?
[C] 纯文本查看 复制代码
?
[C] 纯文本查看 复制代码
?
[C] 纯文本查看 复制代码
?
[C] 纯文本查看 复制代码
?
[C] 纯文本查看 复制代码
?
相关文章推荐
- linux(centos)搭建SVN服务器
- Linux下find命令使用
- CenOS7.1安装VNC——让win7远程桌面linux
- Linux下出现No module named ..的原因
- Linux 忘记root密码并重置root密码
- centos6.5 安装python3.5
- Linux文本处理命令
- Linux Makefile 详细语法
- linux下的inode记录
- Linux下使用Rinetd来实现端口转发
- GCC编译和GDB调试
- 初涉定制linux系统之——自动化安装Centos系统镜像制作
- linux学习笔记2 - linux常用命令
- linux文件系统启动流程 ---笔记整理
- Linux 2.6内核Makefile浅析【转】
- linux进程通信--有名管道
- 常用linux命令
- 远程登录Linux图形化界面
- linux 连接windows 共享文件夹
- linux下邮件查看命令