今天移植了2.6.25的网卡驱动 总结一下
因为在驱动中使用的是虚拟地址,因此要首先将网卡的物理地址映射到虚拟地址
**************************************************************
1 。在include/asm-arm/plat-s3c24xx/common-smdk.h文件中添加
其中必须使用宏__phys_to_pfn 即将物理地址右移12位,跟踪源码可知 与struct map_desc中的pfn相关
#define pSMDK2410_ETH_IO __phys_to_pfn(0x19000000)
#define vSMDK2410_ETH_IO S3C2410_ADDR(0x04000000)
#define SMDK2410_ETH_IRQ IRQ_EINT9
***********************************************************************************
2.我是在arch/arm/mach-s3c2410/mach-smdk2410.c 文件中添加
修改
static struct map_desc smdk2410_iodesc[] __initdata={
{vSMDK2410_ETH_IO, pSMDK2410_ETH_IO, SZ_1M, MT_DEVICE}//添加的
};
*****************************************************************************
4、修改 drivers/net/cs89x0.c
下面是我diff:'+'为我添加出 '-'为原来的代码
+****************************************************************************
/* Event inputs bank 1 - ID 35/bit 3 */
static unsigned int netcard_portlist[] __initdata = {CIRRUS_DEFAULT_BASE, 0};
static unsigned int cs8900_irq_map[] = {CIRRUS_DEFAULT_IRQ, 0, 0, 0};
+#elif defined(CONFIG_ARCH_S3C2410) //Added weibing
+#include <linux/irq.h>
+#include <asm/irq.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm-arm/plat-s3c24xx/common-smdk.h>
+static unsigned int netcard_portlist[] __initdata = { vSMDK2410_ETH_IO +
DEFAULTIOBASE, 0};
+static unsigned int cs8900_irq_map[] = {SMDK2410_ETH_IRQ , 0, 0, 0};
+
+#ifdef request_region
+#undef request_region
+#endif
+#ifdef release_region
+#undef release_region
+#endif
+#define request_region(a,s,n) request_mem_region(a,s,n)
+#define release_region(a,s) release_mem_region(a,s)
#else
static unsigned int netcard_portlist[] __initdata =
{ 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
*************************************************************************************
**************************************************************************
//其中BWSCON BANKCON3必须设置,其用法s3c2410中文手册
@@ -324,6 +348,10 @@
io = dev->base_addr;
irq = dev->irq;
+#ifdef CONFIG_ARCH_S3C2410
+ __raw_writel((__raw_readl(S3C2410_GPGCON)&~(0x3<<2))|(0x2<<2),S3C2410_GPGCON);
+ __raw_writel((__raw_readl(S3C2410_EXTINT1)&~(0x7<<4))|(0x4<<4),S3C2410_EXTINT1);
+ __raw_writel(0x2211d110,S3C2410_BWSCON);
+ __raw_writel(0x1f7c,S3C2410_BANKCON3);
+#endif
if (net_debug)
printk("cs89x0:cs89x0_probe(0x%x)\n", io);
****************************************************************************
***************************************************************************
@@ -386,6 +414,18 @@
{
outw(value, base_addr + (portno << 1));
}
+#elif defined(CONFIG_ARCH_S3C2410)
+static u16
+readword(unsigned long base_addr, int portno)
+{
+ return __raw_readw(base_addr+portno);
+}
+
+static void
+writeword(unsigned long base_addr, int portno,u16 value)
+{
+ __raw_writew(value,base_addr+portno);
+}
#else
static u16
readword(unsigned long base_addr, int portno)
***************************************************************************
**************************************************************************
此处设置MAC地址 ,其值不能随便设置。 其高32为指定的厂商号,即00 E0 4C 4D (为某牌网卡)
后16为可以随便设置,否则在使用ifconfig时出错。
因为在嵌入式版中没有EPROM所以MAC地址不能指定,需自己设置。
@@ -638,7 +678,18 @@
the driver will always do *something* instead of complain that
adapter_cnf is 0. */
-#ifdef CONFIG_SH_HICOSH4
+#if defined CONFIG_ARCH_S3C2410
+ lp->force=FORCE_RJ45;
+ lp->auto_neg_cnf=IMM_BIT;
+
+ dev->dev_addr[0]=0x00; /*setMACaddress*/
+ dev->dev_addr[1]=0xE0;
+ dev->dev_addr[2]=0x4C;
+ dev->dev_addr[3]=0x4D;
+ dev->dev_addr[4]=0x10;
+ dev->dev_addr[5]=0x30;
+
+#elif defined CONFIG_SH_HICOSH4
if (1) {
/* For the HiCO.SH4 board, things are different: we don't
have EEPROM, but there is some data in flash, so we go
*************************************************************************
***************************************************************************
@@ -1278,7 +1329,7 @@
int i;
int ret;
-#if !defined(CONFIG_SH_HICOSH4) && !defined(CONFIG_ARCH_PNX010X) /* uses irq#1, so this won't work */
+#if !defined(CONFIG_SH_HICOSH4) && !defined(CONFIG_ARCH_PNX010X) && !defined
(CONFIG_ARCH_S3C2410) /* uses irq#1, so this won't work */
if (dev->irq < 2) {
/* Allow interrupts to be generated by the chip */
/* Cirrus' release had this: */
*************************************************************************************
*************************************************************************************
@@ -1309,7 +1360,7 @@
else
#endif
{
-#if !defined(CONFIG_MACH_IXDP2351) && !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX010X)
+#if !defined(CONFIG_MACH_IXDP2351) && !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX010X) && !defined(CONFIG_ARCH_S3C2410)
if (((1 << dev->irq) & lp->irq_map) == 0) {
printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
dev->name, dev->irq, lp->irq_map);
*************************************************************************************
*************************************************************************************
@@ -1324,6 +1375,9 @@
writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);
#endif
write_irq(dev, lp->chip_type, dev->irq);
+#if defined(CONFIG_ARCH_S3C2410)
+ set_irq_type(dev->irq, IRQT_RISING);
+#endif
ret = request_irq(dev->irq, &net_interrupt, 0, dev->name, dev);
if (ret) {
if (net_debug)
****************************************************************************************
************************************************************************************
@@ -1394,7 +1448,7 @@
case A_CNF_MEDIA_10B_2: result = lp->adapter_cnf & A_CNF_10B_2; break;
default: result = lp->adapter_cnf & (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2);
}
-#ifdef CONFIG_ARCH_PNX010X
+#if defined(CONFIG_ARCH_PNX0105) || defined(CONFIG_ARCH_S3C2410)
result = A_CNF_10B_T;
#endif
if (!result) {
*******************************************************************************
4 燃后在make menuconfig
[*] Ethernet (10 or 100Mbit) --->
-*- EISA, VLB, PCI and on board controllers
<*> CS89x0 support
make zImage 成功
*********************************************************************************
注:
我在网上看到有人在 drivers/net/Kconfig文件中的config CS89*0配置信息中加入
depend on ARCH_S3C2410
我觉得没有必要的
我验证了一下 确实没有必要的。
因为2.6.25内核源码中并没有USB驱动的初始化程序,因此我添加了相应的代码:
在linux-2.6.25/arch/arm/mach-s3c2410/mach-smdk2410.c文件中添加:
static struct s3c2410_hcd_info usb_s3c2410_info = {
.port[0] = {
.flags = S3C_HCDFLG_USED
},
.port[1] = {
.flags = S3C_HCDFLG_USED
}
};
int __init s3c2410_init_usb(void)
{
unsigned long upllvalue;
printk("USB Control, (c) 2006 pc104\n");
s3c_device_usb.dev.platform_data = &usb_s3c2410_info;
s3c2410_modify_misccr(S3C2410_MISCCR_USBSUSPND0 |
S3C2410_MISCCR_USBSUSPND1, 0x8);
upllvalue = (0x78<<12)|(0x02<<4)|(0x03);
while(upllvalue!=__raw_readl(S3C2410_UPLLCON))
{
__raw_writel(upllvalue,S3C2410_UPLLCON);
mdelay(1);
}
return 0;
}
在此函数中添加了红色部分:
static void __init smdk2410_init(void)
{
platform_add_devices(smdk2410_devices, ARRAY_SIZE(smdk2410_devices));
smdk_machine_init();
s3c2410_init_usb();
}
其对上面代码的解释看下此帖:
http://www.linuxforum.net/forum/showflat.phpCat=&Board=embedded&Number=556915&page=0&view=collapsed&sb=5&o=0&fpart=
拷贝linux-2.6.25/arch/arm/configs/s3c2410_defconfig 缺省配置文件 并命名.config
make menuconfig 再进行配置
1.设备驱动部分设置
General setup --->
[*]Configure standard kernel features (for small systems) --->
[*] Support for hot-pluggable devices
Device Drivers --->
Generic Driver Options --->
<*> Hotplug firmware loading support
Block devices --->
<*> Low Performance USB Block driver
SCSI device support --->
<*> SCSI generic support
<*> SCSI disk support
[*] Probe all LUNs on each SCSI device
USB support --->
<*> Support for Host-side USB
[*] USB device filesystem
<*> OHCI HCD support
<*> USB Mass Storage support
[*] USB Monitor
这里我选择了SCSI设备。
2 文件系统部分设置
File systems --->
DOS/FAT/NT Filesystems --->
<*> MSDOS fs support
<*> VFAT (Windows-95) fs support
(936) Default codepage for FAT
(cp936) Default iocharset for FAT
File systems --->
Partition Types --->
[*] PC BIOS (MSDOS partition tables) support
3 加入一些字体库
Native Language Support --->
<*> Simplified Chinese charset (CP936, GB2312)
<*> NLS UTF8
但我将内核镜像烧入板中后,插入U盘 mount 挂载时出现如下错误:
Unable to load NLS charset cp437
FAT: codepage cp437 not found
mount: mounting sda1 on /mnt failed: Invalid argument
因此我又重新增加了配置选项在 Native Language Support ---> 中
File systems --->
Native Language Support --->
<*> Codepage 437 (United States, Canada)
<*> Simplified Chinese charset (CP936, GB2312)
然后再编译
make zImage
烧入镜像后插入U盘显示如下信息
sd 1:0:0:0: [sda] 129312 512-byte hardware sectors (66 MB)
sd 1:0:0:0: [sda] Write Protect is off
sd 1:0:0:0: [sda] Assuming drive cache: write through
sd 1:0:0:0: [sda] 129312 512-byte hardware sectors (66 MB)
sd 1:0:0:0: [sda] Write Protect is off
sd 1:0:0:0: [sda] Assuming drive cache: write through
sda: sda1
sda: p1 exceeds device capacity
sd 1:0:0:0: [sda] Attached SCSI removable disk
然后mount -t vfat /dev/sda1 /mnt
其中设备文件名是我在安装文件系统时生成的
在/dev/中
mknod sda1 b 8 0
加载成功