分类: LINUX
2012-07-30 19:16:46
实际上 在 /arch/arm/mach-s3c2440/ 下 已有的mini2440.c 已有对dm9000的配置移植
为了实际性的体验 在smdk2440 下移植到mini2440 参考 下面的 实现移植 dm9000
/ 总结 在移植过程中,学会调试和处理移植出现的问题 很重要
基本上,归为下面几点 修改文件的代码格式特别需要注意 ,一般性的问题就是相关代码格式未注意或者 代码拼写出错而导致 make uImage 出现一大堆错误!!!!
【1】设备资源初始化
Linux-2..6.32.2 已经自带了完善的DM9000 网卡驱动驱动(源代码位置:linux-2.6.32.2/drivers/net/dm9000.c),它也是一个平台设备,因此在目标平台初始化代码中,只要填写好相应的结构表即可,具体步骤如下:
(1)确认已经添加了驱动所需的头文件 dm9000.h:
用gedit打开linux-2.6.32.2/arch/arm/mach-mini2440.c,定位到55行附近,加入dm9000.h,如下所示:
#include
#include
#include
#include
#include
#include
#include
(2)填充该平台设备的资源设置
定位到210行附近,如入下面代码:
tatic struct s3c2410_platform_nand mini2440_nand_info = {
.tacls = 20,
.twrph0 = 60,
.twrph1 = 20,
.nr_sets = ARRAY_SIZE(mini2440_nand_sets),
.sets = mini2440_nand_sets,
.ignore_unset_ecc = 1,
};
/* DM9000AEP 10/100 ethernet controller */ //定义DM9000 网卡设备的物理基地址,以便后面用到
#define MACH_MINI2440_DM9K_BASE (S3C2410_CS4 + 0x300)
//再填充该平台设备的资源设置,以便和 DM9000 网卡驱动接口配合起来
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,
}
};
/*
* * The DM9000 has no eeprom, and it's MAC address is set by
* * the bootloader before starting the kernel.
* */
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,
},
};
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, //;把nand flash 设备添加到开发板的设备列表结构
&mini2440_device_eth, //;把网卡平台设备添加到开发板的设备列表结构
};
static void __init mini2440_map_io(void)
【2】调整DM9000 所用的位宽寄存器
因为 Linux-2.6.32.2 的DM9000 网卡驱动并不是专门为mini2440 准备的,所以还要在其源代码中做一些移植工作,如下步骤。
(1)打开linux-2.6.32.2/drivers/net/dm9000.c,定位到41行附近,添加2410 相关的配置定义,如下红色部分:
#include
#include
#include
#include "dm9000.h"
#if defined(CONFIG_ARCH_S3C2410)
#include
#endif
(2) 在dm9000 设备的初始化函数中添加如下红色部分,这里是配置DM9000 所用片选总线的时序,因为mini2440 目前只有一个通过总线外扩的设备,在此设备驱动中直接修改相关的寄存器配置会更加容易理解一些,当然这部分也可以放到mach-mini2440.c 中。
打开linux-2.6.32.2/drivers/net/dm9000.c,定位到1555行附近,加入下面代码:
static int __init
dm9000_init(void)
{
#if defined(CONFIG_ARCH_S3C2410)
unsigned int oldval_bwscon = *(volatile unsigned int *)S3C2410_BWSCON;
unsigned int oldval_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);
}
【3】需要注意的是,本开发板所用的DM9000 网卡并没有外接EEPROM 用以存储MAC 地址,因此系统中的MAC 地址是一个“软”地址,也就是可以通过软件进行修改,可以随意改为其他值。
打开linux-2.6.32.2/drivers/net/dm9000.c,定位到1461行附近,加入下面一行代码:
static int __devinit
dm9000_probe(struct platform_device *pdev)
{
... ...
/* try reading the node address from the attached EEPROM */
//;尝试从EEPROM 读取MAC 地址
for (i = 0; i < 6; i += 2)
dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);
if (!is_valid_ether_addr(ndev->dev_addr) && pdata != NULL) {
mac_src = "platform data";
memcpy(ndev->dev_addr, pdata->dev_addr, 6);
}
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);
}
//;使用“软”MAC 地址: 08:90:90:90:90:90
memcpy(ndev->dev_addr, "\x08\x90\x90\x90\x90\x90", 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);
platform_set_drvdata(pdev, ndev);
ret = register_netdev(ndev);
if (ret == 0)
printk(KERN_INFO "%s: dm9000%c at %p,%p IRQ %d MAC: %pM (%s)\n",
ndev->name, dm9000_type_to_char(db->type),
db->io_addr, db->io_data, ndev->irq,
ndev->dev_addr, mac_src);
return 0;
out:
dev_err(db->dev, "not found (%d).\n", ret);
dm9000_release_board(pdev, db);
free_netdev(ndev);
return ret;
}
实际上到此为止 DM9000 就已经移植结束了。
3.2,编译测试
【1】在编译之前,需要确认在内核中已经配置了网卡驱动
在内核目录下执行:
[root@localhost linux-2.6.32.2]# make menuconfig
在打开的配置菜单Device Drivers --->Network device support ---> Ethernet (10 or 100Mbit) --->
可以看到 dm9000 那项是否被选上。
配置完毕,保存
#make uImage
.......