今天跟大家交流一下移植DM9000驱动的,希望对大家有个借鉴,这样本人也是很自豪的嘛,不扯了,开始吧。这篇文章主要讲一下DM9000移植时地址的计算,以及相对应的内核的配置。依然列出主要内容:
1.内核文件的修改以及相应的原理;
2.DM9000在内核中的配置。
一.内核中的修改
1.简单的硬件介绍
DM9000网卡的驱动是内核中自带的,同样它在内核中的注册也是用platform类型驱动的方式的,也就是说驱动和具体的硬件平台是完全分离的,由上一篇文章的介绍,咱们移植DM9000的主要任务就是在内核中相应的文件中以platform设备的形式注册DM9000芯片在具体电路板上的资源,也就是所谓的设备了呗。既然要注册资源,那咱们先了解了解DM9000和主芯片的了解方式,同时在这里也简单的介绍一下DM9000芯片,先看连接方式吧。如下图:
咱们简单地介绍一下啊,SD0~SD15对应处理器上的DATA0~DATA15,别只看名字,这个总线是命令和数据都能传输的。DM9000芯片上的INT引脚跟S5PV210的EINT7,也就是说跟第七个中断引脚相连,这个会在移植的时候体现出来;通过CMD可以选择是传输数据还是命令;CS#和nGCS1相对应,DM9000上的CS#主要的功能是选通网卡芯片,不过要主要nGCS1,这个引脚表示映射的是S5PV210的bank1,还会再介绍;下面的IOR#和IOW#就是选择是读了还是写了,这个可能猜也会猜着。
2.修改内核文件
修改的还是linux-3.3.5目录下的arch/arm/mach-s5pv210/mach-smdkv210.c这个文件,这个文件当中有对DM9000的注册,但这是与三星的demo板相匹配的注册方法了,因为tiny210板的硬件电路和demo板不一样,所以咱们得修改其中的一些部分,不过仅仅是修改啊,下边是修改后的其中一部分
#include <linux/dm9000.h>你看第一行就是加头文件了,这个是不可少的嘛。可以看出资源包括三部分,其中两部分内存资源,另外一部分是中断。注册中断资源,因为硬件连接有中断嘛;内存资源显然是进行映射的嘛,那为什么要注册两份了,下面是我从DM9000数据手册当中翻译的一段,看完之后应该就豁然开朗了:DM9000可以通过两个地址端口访问DM9000。其中一个端口是INDEX端口,另外一个是DATA端口。当CMD引脚为低电平的时候,访问的是INDEX端口,当CMD引脚是高电平的时候,访问的DATA端口。INDEX端口里面的内容就是DATA端口中的寄存器的地址。在访问任何DATA端口中的寄存器时,首先得把寄存器的地址保存在INDEX端口中。上面的描述能清晰的表达一个意思,就是咱们的驱动中得需要两个地址。注册的第三个资源中,可以看出注册中断就是中断号为7的中断吧,这个硬件电路图相符合。
/* physical address for dm9000a ...*/
#define S5PV210_PA_DM9000_A (0x88000000)
#define S5PV210_PA_DM9000_F (S5PV210_PA_DM9000_A + 0x300c)
static struct resource smdkv210_dm9000_resources[] = {
[0] = {
.start = S5PV210_PA_DM9000_A,
.end = S5PV210_PA_DM9000_A + SZ_1K*4 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = S5PV210_PA_DM9000_F,
.end = S5PV210_PA_DM9000_F + SZ_1K*4 - 1,
.flags = IORESOURCE_MEM,
},
[2] = {
.start = IRQ_EINT(7),
.end = IRQ_EINT(7),
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
},
};
现在解释解释一下"#define S5PV210_PA_DM9000_A (0x88000000)",为什么是0x88000000?因为DM9000的CS#引脚接了nGCS1,也就是网卡接到了ROM控制器的BANK1上,下边是S5PV210具体的映射图
这个映射表清楚的说明,BANK1是从0x88000000开始的,友善自带的系统里这里是0x88001000,这个没什么区别,只要在BANK1的地址范围内就行。
接下来咱们再来解释解释“#define S5PV210_PA_DM9000_F (S5PV210_PA_DM9000_F + 0x300c)”,定义的这个地址中为什么要加0x300c呢?网上有许多在S3C2440和S3C6410上移植DM9000的驱动时,加的是4,而这里加的是0x300c?是不是我弄错了呢,没错,友善官方的也是这个值,我自己也验证过了。要是你在默认的情况加的是4,肯定会出现错误。现在是不是有点意思了,哈哈。这个问题也困惑了我几个小时,经过阅读S5PV210的数据手册,发现有这样一段话,我贴出来啊
这是描述SROM_BW寄存器的,就是SROM总线宽度和等待控制寄存器,不知道翻译的准确不准确,不过大家应该能明白这个意思吧。这个寄存器当中的第五位默认是0,那也就是说SROM_ADDR[22:0]<=HADDR[23:1],看出来了吧,正好向左移了一位,这就明白了,后来我试直接加8或者c都行,正好算做了一个验证。还有另外一种方式就是修改SROM_BW这个寄存器中的第五位,把它从0改成1,就跟移植2440和6410的一样了,那在什么地方修改这个寄存器的值了?其实还在mach-smdkv210.c中,smdkv210_dm9000_init函数,这个函数也需要修改,因为tiny210上用的是BANK1,而demo上用的是BANK5,修改后的如下:
static void __init smdkv210_dm9000_init(void)
{
unsigned int tmp;
gpio_request(S5PV210_MP01(1), "nCS1");
s3c_gpio_cfgpin(S5PV210_MP01(1), S3C_GPIO_SFN(2));
gpio_free(S5PV210_MP01(1));
tmp = ((0<<28)|(0<<24)|(5<<16)|(0<<12)|(0<<8)|(0<<4)|(0<<0));
__raw_writel(tmp, (S5P_SROM_BW+0x08));
tmp = __raw_readl(S5P_SROM_BW);
tmp &= ~(0xf << 4);
tmp |= (1 << 4);
__raw_writel(tmp, S5P_SROM_BW);
}
看到红色的一行了吧,要是打算吧SROM_BW寄存器当的第五位设置成1,用tmp |= ((1<<4)|(1<<5)),取代上面代码中的tmp |= (1<<4),就行了,替换之后,就和移植2440和6410的一样了。我自己做了实验,结果是正确的。要是不替换,那就加8或者c或加0x300c都行。哈哈,现在把移植讲完了,下边开始配置内核吧,可能你也等不急了吧。
二.DM9000的内核配置
要进行DM9000的配置嘛,那咱们就再次进入linux-3.3.5下吧,再次make menuconfig吧。下面我主要以图来说明,尤其是所截图中的高亮部分。首先,进入配置首目录后,选择Networking support------>
选中后,进入Networking support目录中,在这个目录中,选择wireless------------->,如下图:
继续进入wireless目录,在这个目录下选择
选择完这些之后,你应该再次推出到刚进入的界面,然后,选择Device Driver---------->,如下图:
选中之后,进入Device Driver目录,然后选择Network devicesupport ------------>,如下图:
进入这个目录后,选中如下的这么多项,直接看图吧
看到上图中的Ethernet driver support (NEW) ------>了吧,选中它,然后进入其目录,选中红色勾出的部分,如下:
选中后,就退出到Network device support目录,然后选择下图中的高亮选项,如下:
把这项选完之后,就以此退出吧,保存后。重新make uImage,这时编译出的内核就已经有DM9000的驱动了,今天就到这里吧。下一篇文章咱们讲讲制作跟文件系统,哈哈,go on!