开发环境:
主机:fedora 14
虚拟机:vmware workstation 10
交叉编译工具:arm-linux-gcc 4.3.2
开发板:mini2440(2m nor ,64m sdram,256m nand)
内核版本:linux2.6.32.2
上一篇帖子的uImage可以起yaffs2文件系统,但是起不了nfs,我的yaffs2使用nfs打包来的,换一个内核可以起,bootargs也没有问题,可能是这里网卡没有移植造成的,移植结束之后再看能不能起,因为nfs对后面做驱动开发优势比较大,方便调试看现象,不需要每次都烧写进去,所以还是需要能够起nfs的。DM9000内核其实已经是支持了,我们需要根据mini2440的具体的硬件资源做添加和修改。
首先,明确一下mini2440上dm9000的硬件资源,dm9000是直接挂在s3c2440的bank4上面,连接了16条数据线,1条地址线,这条地址线判断是地址还是数据传输,然后通过16条数据线来传输,也就是复用。
一、添加头文件
在mach-mini2440.c中:
添加头文件如下:
#include
二、添加物理基地址宏定义
#define MACH_MINI2440_DM9K_BASE (S3C2410_CS4+0X300)
这个地址是怎么来的呢,这里S3C2410_CS4指的是BANK4的起始地址:0x20000000,后面加上0x300一开始我理解的是,就像我们烧写到sdram的时候虽然sdram挂在0x30000000上,我们烧写的时候还是会留点余地,烧写到0x30008000,这里的0x300和这个是一个意思,但是不超过128M,这样就到下一个BANK去了。
三、添加mini2440_dm9k_resource
static struct resource mini2440_dm9k_resource[]={
[0] = {
.start = MACH_MINI2440_DM9K_BASE,
.end = MACH_MINI2440_DM9K_BASE+3,
.flags = IORESOURCE_MEM
},
[1] = {
.start = MACH_MINI2440_DM9K_BASE_4,
.end = MACH_MINI2440_DM9K_BASE+7,
.flags = IORESOURCE_MEM
},
[2] = {
.start = IRQ_EINT7,
.end = IRQ_EINT7,
.flags = IORESOURCE_IRQ|IORESOURCE_IRQ_HIGHEDGE,
}
};
这个函数是为了填充平台资源,以便和DM9000接口配合起来。
MACH_MINI2440_DM9K_BASE存放的是要发送的地址,MACH_MINI2440_DM9K_BASE+4存放的是要发送的数据,因为是地址和数据复用,所以要分开传送,两次,0代表地址,1代表数据。一个地址需要四个字节传送,所以每次end都要在start基础上+3,这样就是四个字节的大小。数组2则是跟中断有关的资源。
三、设置传送总线位宽
static struct dm9000_plat_data mini2440_dm9k_pdata = {
.flags = (DM9000_PLATF_16BITONLY|DM9000_PLATF_NO_EEPROM),
};
四、添加设备注册函数
static struct platform_device mini2440_device_eth = {
.name = "dm9000",
.id = -1,
.num_resources = ARRAY_SIZE(mini2440_dm9k_resource),
.resource = mini2440_dm9k_resource,
.dev = {
.platform_data = &mini2440_dm9k_pdata,
},
};
五、添加平台设备函数
在mini2440_devices[]中:
static struct platform_device*mini2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&s3c_device_nand,
&s3c_device_eth,
};
六、修改drivers/net/dm9000.c文件
添加头文件:
#ifdefined(CONFIG_ARCH_S3C2410)
#include
#endif
修改dm9000_init函数:
staticint __init
dm9000_init(void)
{
#if defined(CONFIG_ARCH_S3C2410)
unsigned intoldval_bwscon = *(volatile unsigned int *)S3C2410_BWSCON;
unsigned intoldval_bankcon4 = *(volatile unsigned int *)S3C2410_BANKCON4;
*((volatile unsigned int*)S3C2410_BWSCON) = (oldval_bwscon&~(3<<16))|S3C2410_BWSCON_DW4_16|S3C2410_BWSCON_WS4|S3C2410_BWSCON_ST4;
*((volatile unsigned int*)S3C2410_BANKCON4) = 0x1f7c;
#endif
printk(KERN_INFO "%s Ethernet Driver,V%s\n", CARDNAME, DRV_VERSION);
return platform_driver_register(&dm9000_driver);
}
这里:
unsigned int oldval_bwscon = *(volatile unsigned int *)S3C2410_BWSCON;
unsigned intoldval_bankcon4 = *(volatile unsigned int *)S3C2410_BANKCON4;
是将两个寄存器的值保存,volatile是防止编译器因为优化省略掉它,要保证每次都去读他的值。
下面首先设置BWSCON,可以查看datasheet:
这里,oldval_bwscon&~(3<<16)是保留原来寄存器的值,但是对16,17位清零,然后|S3C2410_BWSCON_DW4_16|S3C2410_BWSCON_WS4|S3C2410_BWSCON_ST4,这里的三个宏定义如下,在arch/arm/mach-s3c2410/include/mach/regs-mem.h:
/*bank 4 configurations */
#defineS3C2410_BWSCON_DW4_16 (1<<16)
#defineS3C2410_BWSCON_WS4 (1<<18)
#defineS3C2410_BWSCON_ST4 (1<<19)
所以再对照datasheet就可知,设置总线位宽为16位,使能WAIT,使用UB/LB。
在下面对S3C2410_BANKCON4赋值0x1f7c,这个查看datasheet,可以找到寄存器:
这里0x1f7c分解开来就是:0001 1111 0111 1100,可以自行对照datasheet查看其含义。这里应该是跟时序有关的设置,具体不清楚的可以去网上搜dm9000时序相关的帖子,这里知道其含义,不做深究了。
七、修改dm9000_probe函数
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);
}
memcpy(ndev->dev_addr,"\0x08\0x90\0x90\0x90\0x90\0x90",6);
if(!is_valid_ether_addr(ndev->dev_addr))
dev_warn(db->dev,"%s: Invalid ethernet MAC address. Please "
"set using ifconfig\n",ndev->name);
红色字体为添加部分,大概在1463行。这其实添加“软”mac地址,不添加的话,可能无法挂在我们的nfs,很重要的哦。
八、编译测试
#make menuconfig
DeviceDrivers à
Networkdevice support à
Ethernet(10or 100Mbit) à
<*>DM9000 support
#make zImage
转换成uImage烧写到开发板,这里我从nand启动,然后起了yaffs2之后使用ifconfig没有出来东西,然后我修改bootargs,这里我的是:
setenv bootargs console=ttySAC0root=/dev/nfs nfsroot=192.168.1.122:/opt/rootfsip=192.168.1.226:192.168.1.122:192.168.1.122:255.255.255.0:SMDK2440A.arm9.net:eth0:off
然后重新启动,这时候我的nfs就起来了,输出如下信息:
eth0:link down
IP-Config: Complete:
device=eth0, addr=192.168.1.226, mask=255.255.255.0, gw=192.168.1.122,
host=SMDK2440A, domain=, nis-domain=arm9.net,
bootserver=192.168.1.122, rootserver=192.168.1.122, rootpath=
Lookingup port of RPC 100003/2 on 192.168.1.122
eth0:link up, 100Mbps, full-duplex, lpa 0xDDE1
Lookingup port of RPC 100005/1 on 192.168.1.122
VFS:Mounted root (nfs filesystem) on device 0:14.
Freeinginit memory: 132K
Pleasepress Enter to activate this console.
Processing/etc/profile... Done
/ #
/ # ls
bin etc linuxrc proc sys usr
dev lib mnt sbin tmp var
移植分析结束,如有不正确的地方,还请指出来,大家共同进步!