CS8900A在linux-2.6.16上的移植
关于cs8900a在smdk2410平台,内核2.6.X上的移植网上已有不少转载,这里我简单分析
一下2.6.16内核上的移植。
解决出现如下的问题:
“MM: invalid domain in supersection mapping for 0x18000000000 at 0xe0000000”
基本步骤(引用):
“
(1) #cp cs8900.c ./drivers/net/arm/
#cp cs8900.h ./drivers/net/arm/
并在cs8900_probe()函数中,memset (&priv,0,sizeof (cs8900_t));函数之后添加如下
两条语句:
__raw_writel(0x2211d110,S3C2410_BWSCON);
__raw_writel(0x1f7c,S3C2410_BANKCON3);
注:事实上我并没有加这两行,2.6.16?u-boot-1.1.4已经处理好相应时序了。比如设置bank3
的是上面BWSCON中的“d1”,bankcon3是0x1f4c,与0x1f7c的差别就是:
Tcah [5:4] Address hold time after nGCSn-----片选pin
00 = 0 clock ---->0 01 = 1 clock
10 = 2 clocks 11 = 4 clocks----->3
7-4=3
应该跟电气性能相关
。
(2)修改drivers/net/arm/目录下的Kconfig文件,在最后添加如下内容:
Config ARM_CS8900
tristate "CS8900 support"
depends on NET_ETHERNET && ARM && ARCH_SMDK2410
help
Support for CS8900A chipset based Ethernet cards. If you have a network
(Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available
from as well as .
To compile this driver as a module, choose M here and read
. The module will be
called cs8900.o.
注:内核系统配置文件由2.4版本的config.in变成了2.6版本Kconfig文件,在这个文件里
面添加如上内容,则在运行make menuconfig或者make xconfig命令的时候就会出现:
[ ] CS8900 support
这一选项。
(3)修改drivers/net/arm/目录下的Makefile文件,在最后添加如下内容:
obj-$(CONFIG_ARM_CS8900) += cs8900.o
注:2.6版本内核的Makefile文件也与2.4版本的有所不同。添加以上语句,就会使内核在编
译的时候根据配置将cs8900A的驱动程序以模块或静态的方式编译到内核当中。
(4)在/arch/arm/mach-s3c2410/mach-smdk2410.c文件中,找到smdk2410_iodesc[]结构
数组,添加如下如下内容:
{vSMDK2410_ETH_IO, 0x19000000, SZ_1M, MT_DEVICE}
修改之后变成了:
static struct map_desc smdk2410_iodesc[] __initdata = {
/* nothing here yet */
/* Map the ethernet controller CS8900A */
{vSMDK2410_ETH_IO, 0x19000000, SZ_1M, MT_DEVICE}
};
注:由于在驱动程序的开发的时候,在驱动程序当中所用到的跟设备有关的地址都是虚拟地址,
也就是说驱动程序操作的都是虚拟地址,那么要使驱动程序对设备的操作反映到设备上去,就
得将设备的物理地址映射到正确的虚拟地址上去,从而保证驱动程序对虚拟地址的操作也就是
对相应的物理地址操作。以上添加的语句就是为了将网卡的物理地址(0x19000000)映射到
vSMDK2410_ETH_IO所指向的虚拟地址上去,上面的结构还定义了网卡虚拟地址所占用的区间,
也就是从vSMDK2410_ETH_IO开始的SZ_1M大小的去间,并指定了该区间所指向的域(的属性)。
(疑问:在本开发板上,网卡占用的是CPU的nGCS3片选信号,也就是在Bank3,根据处理器的地
址空间定义,这个地址应该是0x18000000,为什么这里使用的是0x19000000?查找到2.4.18的内
核当中,也是用0x19000000来进行映射。)
”
这里讨论下下 map_desc
struct map_desc {------------------------------2.6.16
unsigned long virtual;---------------虚地址
unsigned long pfn;-------------------Page Frame Number 页帧号
unsigned long length;
unsigned int type;
};
struct map_desc {------------------------------2.6.9
13 unsigned long virtual;
14 unsigned long physical;------------物理地址
15 unsigned long length;
16 unsigned int type;
17 };
pfn / physical 这两者是什么关系呢?
先看调用它们的函数
void __init create_mapping(struct map_desc *md)-------------2.6.16
{
unsigned long virt, length;
int prot_sect, prot_l1, domain;
pgprot_t prot_pte;
unsigned long off = (u32)__pfn_to_phys(md->pfn);
if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
printk(KERN_WARNING "BUG: not creating mapping for "
"0x%08llx at 0x%08lx in user region\n",
__pfn_to_phys((u64)md->pfn), md->virtual);
return;
}
if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx "
"overlaps vmalloc space\n",
__pfn_to_phys((u64)md->pfn), md->virtual);
}
domain = mem_types[md->type].domain;
prot_pte = __pgprot(mem_types[md->type].prot_pte);
prot_l1 = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain);
prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain);
/*
* Catch 36-bit addresses
*/
if(md->pfn >= 0x100000) {
if(domain) {
printk(KERN_ERR "MM: invalid domain in supersection "
"mapping for 0x%08llx at 0x%08lx\n",
__pfn_to_phys((u64)md->pfn), md->virtual);
return;
}
if((md->virtual | md->length | __pfn_to_phys(md->pfn))
/*这里copy一些定义作为注释
Convert a physical address to a Page Frame Number and back
*/
//#define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT)
//#define __pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)
//#ifndef _ASMARM_PAGE_H
//#define _ASMARM_PAGE_H
//#include
/* PAGE_SHIFT determines the page size */
//#define PAGE_SHIFT 12
问题就在这儿了,两者是移12位的关系
& ~SUPERSECTION_MASK) {
printk(KERN_ERR "MM: cannot create mapping for "
"0x%08llx at 0x%08lx invalid alignment\n",
__pfn_to_phys((u64)md->pfn), md->virtual);
return;
}
/*
* Shift bits [35:32] of address into bits [23:20] of PMD
* (See ARMv6 spec).
*/
off |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20);
}
virt = md->virtual;
off -= virt;
length = md->length;
...........
...........
...........
}
结论:
关于linux-2.6.16的头文件就应该改成
#ifndef _INCLUDE_SMDK2410_H_
#define _INCLUDE_SMDK2410_H_
#include
#define pSMDK2410_ETH_IO __phys_to_pfn(0x19000000)
#define vSMDK2410_ETH_IO 0xE0000000
#define SMDK2410_ETH_IRQ IRQ_EINT9
#endif // _INCLUDE_SMDK2410_H_
你可以使用这个链接引用该篇文章 http://publishblog.blogchina.com/blog/tb.b?diaryID=4914641
- 评论人:zycfrank
2007-05-17 17:22:46
|
||||
你好,我现在在做2.6.14内核上的CS8900移植,就是找不到可以用的CS8900源文件,希望你给我一份
|
||||
- 评论人:songh717
2007-03-18 20:02:34
|
||||
大侠你好,我在linux-12.6.15上按照你的办法进行8900的移植,并且#define pSMDK2410_ETH_IO __phys_to_pfn(0x19000000)
|
||||
- 评论人:hiboy
2007-02-08 17:26:40
|
||||
求cs8900.c 和cs8900.h文件。谢谢
|
||||
- 评论人:weibing
2007-02-06 12:00:22
|
||||
十分感谢,困扰我一整天的问题终于解决。添加
|
||||
- 评论人:weibing
2007-02-06 12:00:05
|
||||
十分感谢,困扰我一整天的问题终于解决。添加
|
||||
- 评论人:烂人
2007-01-11 19:15:48
|
||||
牛人阿.
|
||||
- 评论人:烂人
2007-01-11 19:15:44
|
||||
牛人阿.
|
||||
- 评论人:zw
2006-12-24 16:17:55
|
||||
谢谢,能给我一份源代码吗?zw69212@163.com |
||||
- 评论人:fanni
2006-12-06 20:02:13
|
||||
您好大侠 恳请您发2.6下的8900.C及8900.h这两个文件给我 非常感谢!Emil:qianfan726@126.com |
||||
- 评论人:fanni
2006-12-06 20:00:49
|
||||
您好大侠 恳请您发2.6下的8900.C及8900.h这两个文件给我 非常感谢! |
||||
- 评论人:anonymous
2006-10-19 11:07:02
|
||||
我也找不到8900的驱动,给我一份吧,谢谢2008 |
||||
- 评论人:anonymous
2006-09-20 15:53:38
|
||||
您好,我现在正在做8900在26上的移植,但怎么找都找不到8900和8900两个文件,您能发一份到我邮箱吗,万分感谢 |
||||