分类: 嵌入式
2010-05-22 11:11:29
留下这两项就够了,S3C2400 Machines ---> 、S3C2410 Machines --->、S3C2412 Machines --->、S3C2442 Machines --->、S3C2443 Machines --->里的项目全部“N”掉。 这两个选项是区分你的目标芯片是2410还是2440的关键选项!! 二、系统初始化时的芯片晶振频率的修改,修改arch/arm/mach-s3c2440/mach- smdk2440.c ...... static void __init smdk2440_map_io(void) { s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs)); } ...... 如果没有改这个参数,系统启动时到了"done, booting the kernel."之后就会出现乱码现象或是没有输出。我一开始就碰到了这个麻烦。出现此类乱码或没有输出现象的另一个原因可能是你的bootloader 对CPU的主频和分频的设置不正确。SBC2440V4的设置最好是时钟频率405MHz,分频比为1:4:8,不然有可能出现上述现象。请看参考资料 (1)。 三、开发板四个LED指示灯的驱动修改 SBC2440V4和SMDK2440一样有四个LED指示灯。指示用的GPIO口不一样。参考SBC2440V4的硬件说明书,修改/arch /arm/plat-s3c24xx/common-smdk.c如下: ...... static struct s3c24xx_led_platdata smdk_pdata_led4 = { .gpio = S3C2410_GPB5, .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE, .name = "led4", .def_trigger = "timer", }; static struct s3c24xx_led_platdata smdk_pdata_led5 = { .gpio = S3C2410_GPB6, .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE, .name = "led5", .def_trigger = "nand-disk", }; static struct s3c24xx_led_platdata smdk_pdata_led6 = { .gpio = S3C2410_GPB7, .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE, .name = "dm9000", }; static struct s3c24xx_led_platdata smdk_pdata_led7 = { .gpio = S3C2410_GPB8, .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE, .name = "cs89x0", }; ...... void __init smdk_machine_init(void) { /* Configure the LEDs (even if we have no LED support)*/ s3c2410_gpio_cfgpin(S3C2410_GPB5, S3C2410_GPB5_OUTP); s3c2410_gpio_cfgpin(S3C2410_GPB6, S3C2410_GPB6_OUTP); s3c2410_gpio_cfgpin(S3C2410_GPB7, S3C2410_GPB7_OUTP); s3c2410_gpio_cfgpin(S3C2410_GPB8, S3C2410_GPB8_OUTP); s3c2410_gpio_setpin(S3C2410_GPB5, 1); s3c2410_gpio_setpin(S3C2410_GPB6, 1); s3c2410_gpio_setpin(S3C2410_GPB7, 0); s3c2410_gpio_setpin(S3C2410_GPB8, 0); if (machine_is_smdk2443()) smdk_nand_info.twrph0 = 50; s3c_device_nand.dev.platform_data = &smdk_nand_info; platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs)); s3c2410_pm_init(); } ...... 修改成功的现象,启动时LED1和LED2会亮一下;nand flash 读写时LED2会闪动;dm9000有网络活动时,LED3会亮;cs8900有网络活动时,LED4会亮。由于dm9000是作为NFS挂载的网卡,所 以LED3亮的时间比较多。 四、修改/driver/net/Kconfig文件,使其在配置时出现cs89x0的选项。 ...... config CS89x0 tristate "CS89x0 support" ---help--- depends on NET_PCI && (ISA || MACH_IXDP2351 || ARCH_IXDP2X01 || ARCH_PNX010X) Support for CS89x0 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 cs89x0. 就是使 depends on NET_PCI && (ISA || MACH_IXDP2351 || ARCH_IXDP2X01 || ARCH_PNX010X)那一句失效。我是把它放到了 ---help---下面,你也可以把它删了。 以下是双网卡的移植,首先要说明的是如果都编译进内核中,双网卡在启动时会无法挂载NFS,会出现IP配置 失败的提示。单独编译时都不会出现这种情况。原因我不知道。(那位大侠如果解决了记得通知一声) 经过多次试验发现:要实现双网卡,又要挂载NFS根文件系统最好的配置是将DM9000编译进内核(速度快),将 CS8900作为模块在启动后挂载。以下的移植就是针对这种情况修改的。 五、修改/driver/net/cs89x0.c文件,使其匹配SBC2440V4和cs8900的硬件 配置。(并添加LED4在有网络操作时点亮的功能)...... #include #include #include #include #if ALLOW_DMA #include #endif #include "cs89x0.h" //**********************tekkaman************************* #include #include #include #include #include #include #define CS8900_BASE (S3C2440_VA_ISA_CS8900) #define CS8900_IRQ IRQ_EINT9 //**********************tekkaman***************************** static char version[] __initdata = "cs89x0.c: v2.4.3-pre1 Russell Nelson , Andrew Morton \n[/email] "; DEFINE_LED_TRIGGER(cs89x0_led_trigger); #define DRV_NAME "cs89x0" ...... #define CIRRUS_DEFAULT_IRQ VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* 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}; #else static unsigned int netcard_portlist[] __initdata = {CS8900_BASE, 0}; static unsigned int cs8900_irq_map[] = {CS8900_IRQ,0}; #endif /* Index to functions, as function prototypes. */ static int cs89x0_probe1(struct net_device *dev,unsigned int ioaddr, int modular); ...... //static int get_eeprom_cksum(int off, int len, int *buffer); ...... struct net_device * __init cs89x0_probe(int unit) { struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); unsigned int *port; int err = 0; unsigned int irq; unsigned int io; //tekkaman static int once=0; unsigned int value; //tekkaman if (!dev) return ERR_PTR(-ENODEV); sprintf(dev->name, "eth%d", unit); netdev_boot_setup_check(dev); //******************************tekkaman******************************** if (once) { return -ENXIO; } value = __raw_readl(S3C2410_BWSCON); value &= ~(S3C2410_BWSCON_WS3|S3C2410_BWSCON_ST3|S3C2410_BWSCON_DW3_32); value |= (S3C2410_BWSCON_WS3|S3C2410_BWSCON_ST3|S3C2410_BWSCON_DW3_16); __raw_writel(value, S3C2410_BWSCON); value=0; value = (S3C2410_BANKCON_Tacs0|S3C2410_BANKCON_Tcos4|S3C2410_BANKCON_Tacc14|S3C2410_BANKCON_Tcoh1|S3C2410_BANKCON_Tcah4|S3C2410_BANKCON_Tacp6|S3C2410_BANKCON_PMCnorm); __raw_writel(value,S3C2410_BANKCON3); set_irq_type(CS8900_IRQ,IRQ_TYPE_EDGE_RISING ); s3c2410_gpio_cfgpin(S3C2410_GPG1, S3C2410_GPG1_EINT9); s3c2410_gpio_pullup(S3C2410_GPG1, 0); if(dev->base_addr==0){ dev->base_addr = CS8900_BASE ; dev->irq = CS8900_IRQ; once++; } led_trigger_register_simple("cs89x0", &cs89x0_led_trigger); //***********************************tekkaman************************************ io = dev->base_addr; irq = dev->irq; ...... } ...... #else 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); } #endif ...... #if 0 static int __init get_eeprom_cksum(int off, int len, int *buffer) { int i, cksum; cksum = 0; for (i = 0; i ...... static int __init cs89x0_probe1(struct net_device *dev, unsigned int ioaddr, int modular) { struct net_local *lp = netdev_priv(dev); static unsigned version_printed; int i; int tmp; unsigned rev_type = 0; // int eeprom_buff[CHKSUM_LEN]; int retval; unsigned char ne_defethaddr[]={0x08,0x08,0x08,0x08,0x27,0x12,0};//tekkaman SET_MODULE_OWNER(dev); /* Initialize the device structure. */ if (!modular) { memset(lp, 0, sizeof(*lp)); spin_lock_init(&lp->lock); #ifndef MODULE #if ALLOW_DMA if (g_cs89x0_dma) { lp->use_dma = 1; lp->dma = g_cs89x0_dma; lp->dmasize = 16; /* Could make this an option... */ } #endif // lp->force = g_cs89x0_media__force; lp->force = (FORCE_RJ45 | FORCE_FULL); lp->auto_neg_cnf=IMM_BIT; ...... #if 0 if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) == (EEPROM_OK|EEPROM_PRESENT)) { /* Load the MAC. */ for (i=0; i dev_addr[i*2] = Addr & 0xFF; dev->dev_addr[i*2+1] = Addr >> 8; } ...... if (net_debug > 1) printk(KERN_DEBUG "%s: new adapter_cnf: 0x%x\n", dev->name, lp->adapter_cnf); } #endif for (i = 0; i dev_addr = ne_defethaddr; } /* allow them to force multiple transceivers. If they force multiple, autosense */ { int count = 0; if (lp->force & FORCE_RJ45) {lp->adapter_cnf |= A_CNF_10B_T; count++; } if (lp->force & FORCE_AUI) {lp->adapter_cnf |= A_CNF_AUI; count++; } if (lp->force & FORCE_BNC) {lp->adapter_cnf |= A_CNF_10B_2; count++; } if (count > 1) {lp->adapter_cnf |= A_CNF_MEDIA_AUTO; } else if (lp->force & FORCE_RJ45){lp->adapter_cnf |= A_CNF_MEDIA_10B_T; } else if (lp->force & FORCE_AUI) {lp->adapter_cnf |= A_CNF_MEDIA_AUI; } else if (lp->force & FORCE_BNC) {lp->adapter_cnf |= A_CNF_MEDIA_10B_2; } } ...... static int detect_tp(struct net_device *dev) { ...... if ((readreg(dev, PP_LineST) & LINK_OK) == 0) return DETECTED_NONE; lp->force = (FORCE_RJ45 | FORCE_FULL); lp->auto_neg_cnf=IMM_BIT; if (lp->chip_type == CS8900) { switch (lp->force & 0xf0) { ...... } ...... static int net_open(struct net_device *dev) { ...... if (i >= CS8920_NO_INTS) { writereg(dev, PP_BusCTL, 0); /* disable interrupts. */ printk(KERN_ERR "cs89x0: can't get an interrupt\n"); ret = -EAGAIN; goto bad_out; } } else #endif { #if !defined(CONFIG_MACH_IXDP2351) && !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX010X) && !defined(CONFIG_ARCH_S3C2410) if (((1 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); ret = -EAGAIN; goto bad_out; } #endif ...... /* set the Ethernet address */ for (i=0; i dev_addr[i*2] | (dev->dev_addr[i*2+1] /* while we're testing the interface, leave interrupts disabled */ writereg(dev, PP_BusCTL, MEMORY_ON); /* Set the LineCTL quintuplet based on adapter configuration read from EEPROM */ if ((lp->adapter_cnf & A_CNF_EXTND_10B_2) && (lp->adapter_cnf & A_CNF_LOW_RX_SQUELCH)) lp->linectl = LOW_RX_SQUELCH; else lp->linectl = 0; lp->adapter_cnf |= A_CNF_10B_T | A_CNF_MEDIA_10B_T ; /* check to make sure that they have the "right" hardware available */ switch(lp->adapter_cnf & A_CNF_MEDIA_TYPE) { case A_CNF_MEDIA_10B_T: result = lp->adapter_cnf & A_CNF_10B_T; break; case A_CNF_MEDIA_AUI: result = lp->adapter_cnf & A_CNF_AUI; break; 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); } ...... } ...... static int net_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = netdev_priv(dev); led_trigger_event(cs89x0_led_trigger, LED_FULL); ...... led_trigger_event(cs89x0_led_trigger, LED_OFF); return 0; } /* The typical workload of the driver: Handle the network interface interrupts. */ static irqreturn_t net_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; struct net_local *lp; unsigned int ioaddr, status; int handled = 0; ...... } ...... static void net_rx(struct net_device *dev) { struct net_local *lp = netdev_priv(dev); struct sk_buff *skb; int status, length; led_trigger_event(cs89x0_led_trigger, LED_FULL); unsigned int ioaddr = dev->base_addr; status = readword(ioaddr, RX_FRAME_PORT); length = readword(ioaddr, RX_FRAME_PORT); ...... led_trigger_event(cs89x0_led_trigger, LED_OFF); } ...... #ifdef MODULE static struct net_device *dev_cs89x0; /* * Support the 'debug' module parm even if we're compiled for non-debug to * avoid breaking someone's startup scripts */ static unsigned int io=CS8900_BASE; static unsigned int irq=CS8900_IRQ; static int debug; static char media[8]="rj45"; static int duplex=-1; static int use_dma; /* These generate unused var warnings if ALLOW_DMA = 0 */ static int dma; static int dmasize=16; /* or 64 */ module_param(io, uint, 0); module_param(irq, uint, 0); module_param(debug, int, 0); ...... int __init init_module(void) { struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); struct net_local *lp; int ret = 0; #if DEBUGGING net_debug = debug; #else debug = 0; #endif //tekkaman unsigned int value; value = __raw_readl(S3C2410_BWSCON); value &= ~(S3C2410_BWSCON_WS3|S3C2410_BWSCON_ST3|S3C2410_BWSCON_DW3_32); value |= (S3C2410_BWSCON_WS3|S3C2410_BWSCON_ST3|S3C2410_BWSCON_DW3_16); __raw_writel(value, S3C2410_BWSCON); value=0; value = (S3C2410_BANKCON_Tacs0|S3C2410_BANKCON_Tcos4|S3C2410_BANKCON_Tacc14|S3C2410_BANKCON_Tcoh1|S3C2410_BANKCON_Tcah4|S3C2410_BANKCON_Tacp6|S3C2410_BANKCON_PMCnorm); __raw_writel(value,S3C2410_BANKCON3); set_irq_type(CS8900_IRQ,IRQ_TYPE_EDGE_RISING ); s3c2410_gpio_cfgpin(S3C2410_GPG1, S3C2410_GPG1_EINT9); s3c2410_gpio_pullup(S3C2410_GPG1, 0); led_trigger_register_simple("cs89x0", &cs89x0_led_trigger); //tekkaman if (!dev) return -ENOMEM; ...... } ...... 特别说明:除了总线配置语句一定要加,否则网 卡运行时会出现“time out”的错误之外,还有一个十分重要的地方:在驱动中存储 基地址 和中断 的变量一点要统一定义为unsigned int 否则会出错。 六、修改/driver/net/dm9000.c文件,使其匹配SBC2440V4和DM9000的硬件配置(并添加LED3在有网络操作时点亮的功能) ...... #include //LED驱动头文件 ...... //**********************tekkaman************************* #include #include #include #include #include #include #define DM9000_IRQ IRQ_EINT7 //**********************tekkaman***************************** /* * Transmit timeout, default 5 seconds. */ static int watchdog = 5000; module_param(watchdog, int, 0400); MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds"); DEFINE_LED_TRIGGER(dm9000_led_trigger); ...... static void dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value); //static u16 read_srom_word(board_info_t *, int); static void dm9000_rx(struct net_device *); static void dm9000_hash_table(struct net_device *); //tekkaman #undef DM9000_PROGRAM_EEPROM //tekkaman #ifdef DM9000_PROGRAM_EEPROM static void program_eeprom(board_info_t * db); #endif ...... #if 0 //def CONFIG_NET_POLL_CONTROLLER /* *Used by netconsole */ static void dm9000_poll_controller(struct net_device *dev) { disable_irq(dev->irq); dm9000_interrupt(dev->irq,dev); enable_irq(dev->irq); } #endif ...... static int dm9000_probe(struct platform_device *pdev) { struct dm9000_plat_data *pdata = pdev->dev.platform_data; struct board_info *db; /* Point a board information structure */ struct net_device *ndev; unsigned char ne_defethaddr[]={0x08,0x08,0x08,0x08,0x12,0x27,0};//tekkaman unsigned long base; int ret = 0; int iosize; int i; u32 id_val; //******************************tekkaman******************************** unsigned int value; static int once=0; if (once) { return -ENXIO; } //tekkaman value = __raw_readl(S3C2410_BWSCON); value &= ~(S3C2410_BWSCON_WS4|S3C2410_BWSCON_ST4|S3C2410_BWSCON_DW4_32); value |= (S3C2410_BWSCON_ST4|S3C2410_BWSCON_DW4_16); __raw_writel(value, S3C2410_BWSCON); value=0; value = (S3C2410_BANKCON_Tacs4|S3C2410_BANKCON_Tcos4|S3C2410_BANKCON_Tacc14|S3C2410_BANKCON_Tcoh4|S3C2410_BANKCON_Tcah4|S3C2410_BANKCON_Tacp6|S3C2410_BANKCON_PMCnorm); __raw_writel(value,S3C2410_BANKCON4); set_irq_type(DM9000_IRQ,IRQ_TYPE_LEVEL_HIGH ); s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_EINT7); s3c2410_gpio_pullup(S3C2410_GPF7, 0); //******************************tekkaman******************************** /* Init network device */ ndev = alloc_etherdev(sizeof (struct board_info)); if (!ndev) { printk("%s: could not allocate device.\n", CARDNAME); return -ENOMEM; } ...... #if 0 def CONFIG_NET_POLL_CONTROLLER ndev->poll_controller = &dm9000_poll_controller; #endif #ifdef DM9000_PROGRAM_EEPROM program_eeprom(db); #endif db->msg_enable = NETIF_MSG_LINK; db->mii.phy_id_mask = 0x1f; db->mii.reg_num_mask = 0x1f; db->mii.force_media = 0; db->mii.full_duplex = 0; db->mii.dev = ndev; db->mii.mdio_read = dm9000_phy_read; db->mii.mdio_write = dm9000_phy_write; /* Read SROM content */ //tekkaman /* for (i = 0; i srom) = read_srom_word(db, i); */ /* Set Node Address */ for (i = 0; i dev_addr = ior(db, i+DM9000_PAR); //tekkaman if (!is_valid_ether_addr(ndev->dev_addr)) { /* try reading from mac */ printk("%s: Invalid ethernet MAC address." " Load ne_defethaddr !! \n ", ndev->name); for (i = 0; i dev_addr = ne_defethaddr; } if (!is_valid_ether_addr(ndev->dev_addr)) printk("%s: Invalid ethernet MAC address. Please " "set using ifconfig\n", ndev->name); ...... /* * Initilize dm9000 board */ static void dm9000_init_dm9000(struct net_device *dev) { board_info_t *db = (board_info_t *) dev->priv; PRINTK1("entering %s\n",__FUNCTION__); ...... /* Init Driver variable */ db->tx_pkt_cnt = 0; db->queue_pkt_len = 0; dev->trans_start = 0; spin_lock_init(&db->lock); } static int dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev) { board_info_t *db = (board_info_t *) dev->priv; PRINTK3("dm9000_start_xmit\n"); led_trigger_event(dm9000_led_trigger, LED_FULL); if (db->tx_pkt_cnt > 1) return 1; ...... led_trigger_event(dm9000_led_trigger, LED_OFF); return 0; } ...... static void dm9000_rx(struct net_device *dev) { board_info_t *db = (board_info_t *) dev->priv; struct dm9000_rxhdr rxhdr; struct sk_buff *skb; u8 rxbyte, *rdptr; bool GoodPacket; int RxLen; /* Check packet ready or not */ do { led_trigger_event(dm9000_led_trigger, LED_FULL); ior(db, DM9000_MRCMDX); /* Dummy read */ ...... led_trigger_event(dm9000_led_trigger, LED_OFF); } while (rxbyte == DM9000_PKT_RDY); } /* * Read a word data from SROM */ #if 0 static u16 read_srom_word(board_info_t * db, int offset) { iow(db, DM9000_EPAR, offset); iow(db, DM9000_EPCR, EPCR_ERPRR); mdelay(8); /* according to the datasheet 200us should be enough, but it doesn't work */ iow(db, DM9000_EPCR, 0x0); return (ior(db, DM9000_EPDRL) + (ior(db, DM9000_EPDRH) ...... static int __init dm9000_init(void) { printk(KERN_INFO "%s Ethernet Driver\n", CARDNAME); led_trigger_register_simple("dm9000", &dm9000_led_trigger); return platform_driver_register(&dm9000_driver); /* search board and register */ } ...... 特别说明:static int dm9000_probe(struct platform_device *pdev)函数中的总线配置语句一定要加,否则网卡运行时会 出现“time out”的错误。 七、修改文件/arch/arm/mach-s3c2440/mach-smdk2440.c,增加对DM9000和CS8900的配置信息。 ...... #include #define DM9000_BASE (vDM9000_BASE)#define DM9000_IRQ IRQ_EINT7#define pDM9000_BASE S3C2440_PA_ISA_DM9000#define vDM9000_BASE S3C2440_VA_ISA_DM9000#define CS8900_BASE (vCS8900_BASE)#define CS8900_IRQ IRQ_EINT9#define pCS8900_BASE S3C2440_PA_ISA_CS8900#define vCS8900_BASE S3C2440_VA_ISA_CS8900 static struct map_desc smdk2440_iodesc[] __initdata = { /* ISA IO Space map (memory space selected by A24) */ { .virtual = (u32)S3C24XX_VA_ISA_WORD, .pfn = __phys_to_pfn(S3C2410_CS1), .length = 0x10000, .type = MT_DEVICE, }, { .virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000, .pfn = __phys_to_pfn(S3C2410_CS1 + (1 .length = SZ_4M, .type = MT_DEVICE, }, { .virtual = (u32)S3C24XX_VA_ISA_BYTE, .pfn = __phys_to_pfn(S3C2410_CS1), .length = 0x10000, .type = MT_DEVICE, }, { .virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000, .pfn = __phys_to_pfn(S3C2410_CS1 + (1 .length = SZ_4M, .type = MT_DEVICE, }, { .virtual = S3C2440_VA_ISA_DM9000, .pfn = S3C2440_PA_ISA_DM9000, .length = S3C2440_SZ_ISA_DM9000, .type = MT_DEVICE, }, { .virtual = S3C2440_VA_ISA_CS8900, .pfn = S3C2440_PA_ISA_CS8900, .length = S3C2440_SZ_ISA_CS8900, .type = MT_DEVICE, } };...... struct dm9000_plat_data tekkaman2440_dm9000 = { .flags= DM9000_PLATF_16BITONLY};static struct resource s3c2440_dm9000_resource[] = { [0] = { .start = DM9000_BASE, .end = DM9000_BASE + 0xff, .flags = IORESOURCE_MEM, }, [1] = { .start = DM9000_IRQ, .end = DM9000_IRQ, .flags = IORESOURCE_IRQ, }};struct platform_device s3c_device_dm9000 = { .name = "dm9000", .id = -1, .num_resources = ARRAY_SIZE(s3c2440_dm9000_resource), .resource = s3c2440_dm9000_resource, .dev = { .platform_data = &tekkaman2440_dm9000, }}; static struct platform_device *smdk2440_devices[] __initdata = { &s3c_device_usb, &s3c_device_lcd, &s3c_device_wdt, &s3c_device_i2c, &s3c_device_iis, &s3c_device_dm9000 }; ...... 八、修改文件/include/asm-arm/arch-s3c2410/map.h,增加DM9000和CS8900的配置信息。 ...... /* ISA style IO, for each machine to sort out mappings for, if it * implements it. We reserve two 16M regions for ISA. */ #define S3C24XX_VA_ISA_WORD S3C2410_ADDR(0x02000000) #define S3C24XX_VA_ISA_BYTE S3C2410_ADDR(0x03000000) /***************tekkaman****************************/#define S3C2440_VA_ISA_DM9000 S3C2410_ADDR(0x02100300)#define S3C2440_PA_ISA_DM9000 __phys_to_pfn(0x20000300)#define S3C2440_SZ_ISA_DM9000 SZ_1M#define S3C2440_VA_ISA_CS8900 S3C2410_ADDR(0x02200300)#define S3C2440_PA_ISA_CS8900 __phys_to_pfn(0x19000300)#define S3C2440_SZ_ISA_CS8900 SZ_1M /**********************tekkaman********************/ ...... 特别说明:至于CS8900的物理地址的配置#define S3C2440_PA_ISA_CS8900 __phys_to_pfn(0x19000300),不一定非得0x19000300,也可以是0x1B000300、0x1D000300、 0x1F000300,这是由于SBC2440V4的CS8900连接基本和SDMK2410的是一样的,使用了ADDR24脚作为类似使能的管脚。这样 的设计是为了系统扩展的方便。 九、配置内核。 Networking ---> Networking options ---> [ ] IP: DHCP support [ ] IP: BOOTP support [ ] IP: RARP support 如果你的cs8900是编译进内核,这三项最好要去掉。如果你和我一样是编译成模块,“Y”、“M”和“N”都无所谓。 Device Drivers ---> Network device support ---> Ethernet (10 or 100Mbit) ---> DM9000 support CS89x0 support 如果双网卡都编译进内核中,在启动时会无法挂载NFS,会出现IP配置失败的提示。单独编译时都不会出现这种情况。 最后就是make zImage 和make modules。将/drivers/net/cs89x0.ko复制到根文件系统中,启动后挂载。以下是我系统的一些信息: [Tekkaman2440@SBC2410]#cd /lib/modules/ [Tekkaman2440@SBC2410]#insmod cs89x0.ko eth%d: cs8900 rev K found at 0xf2200300 cs89x0 media RJ-45, IRQ 53, programmed I/O, MAC 08:08:08:08:27:12 [Tekkaman2440@SBC2410]#ifconfig eth1 192.168.0.22 eth1: using full-duplex 10Base-T (RJ-45) [Tekkaman2440@SBC2410]#ping 192.168.0.1 PING 192.168.0.1 (192.168.0.1): 56 data bytes 64 bytes from 192.168.0.1: seq=0 ttl=64 time=4.977 ms 64 bytes from 192.168.0.1: seq=1 ttl=64 time=0.633 ms 64 bytes from 192.168.0.1: seq=2 ttl=64 time=0.617 ms 64 bytes from 192.168.0.1: seq=3 ttl=64 time=0.601 ms 64 bytes from 192.168.0.1: seq=4 ttl=64 time=0.640 ms 64 bytes from 192.168.0.1: seq=5 ttl=64 time=0.621 ms 64 bytes from 192.168.0.1: seq=6 ttl=64 time=0.723 ms 64 bytes from 192.168.0.1: seq=7 ttl=64 time=0.623 ms --- 192.168.0.1 ping statistics --- 8 packets transmitted, 8 packets received, 0% packet loss round-trip min/avg/max = 0.601/1.179/4.977 ms [Tekkaman2440@SBC2410]#ifconfig eth0 Link encap:Ethernet HWaddr 08:08:08:08:12:27 inet addr:192.168.1.2 Bcast:192.168.1.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:3485 errors:0 dropped:0 overruns:0 frame:0 TX packets:2382 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:2704784 (2.5 MiB) TX bytes:422360 (412.4 KiB) Interrupt:51 Base address:0x300 eth1 Link encap:Ethernet HWaddr 08:08:08:08:27:12 inet addr:192.168.0.22 Bcast:192.168.0.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:36 errors:0 dropped:0 overruns:0 frame:0 TX packets:9 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:4513 (4.4 KiB) TX bytes:826 (826.0 B) Interrupt:53 Base address:0x300 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) |