dm9000驅動移植 之二
DM9000移植一例
2
推薦 在前面移植好內核和文件系統之後,開始考慮網卡的通信了。網上好多關於DM9000驅動的例子,大同小異,但是一律照搬都是不行,最多的只能發現設備,到最後還是ping不通,花費九牛二虎之力,終於還是弄好了。
看到ping通其他主機,真是舒了一口氣。
首先,移植驅動要做的這麼幾個事情
1、 要讓系統能檢測到設備
2、 初始化它
3、 讓驅動找到收發的接口,一般也就是中斷/DMA(具體的收發一般都是驅動已經寫好了的,不用我們多動腦筋)
要讓系統能檢測到設備,首先要知道網卡的基地址。以我的板子爲例,DM9000的CS接在B_nGCS5上,所以基址是0x28000000,在include/asm-arm/arch-s3c2410/map.h中有詳細的定義如下
#define S3C2410_CS0 (0x00000000)
#define S3C2410_CS1 (0x08000000)
#define S3C2410_CS2 (0x10000000)
#define S3C2410_CS3 (0x18000000)
#define S3C2410_CS4 (0x20000000)
#define S3C2410_CS5 (0x28000000)
#define S3C2410_CS6 (0x30000000)
#define S3C2410_CS7 (0x38000000)
我們看到的是8個片選,s3c2440將4G(0x40000000)的地址空間通過8個片選劃分爲8個區間,我們最常看到的地址比如0x30200000,這是內存地址,因爲內存接的CS6,它的地址是以0x3開頭的。很明顯,DM9000接在CS5上,基址應該就是0x28000000了,可是這裏還有一個疑問,爲什麼會是0x28000300,這個問題我也沒弄明白,不過在後來移植CS8900時,我發現CS8900A的手冊中有這麼一句話:當CS8900復位時,16字節連續的端口被分配在偏移地址300H處,這個地址就是CS8900的I/O基地址。就權且這麼用吧,反正我試了,除非加上這個300,否則系統找不到DM9000這個設備(後來的CS8900也如此)。
好了,不羅嗦了,先把工作做完。
移植步驟
1. 修改arch/arm/plat-s3c24xx/devs.c,加入dm9000的信息,並使用EXPORT_SYMBOL 宏將platform_device s3c_device_dm9000導出,在smdk2410.c中會用到
//===========================================================================
// dm9000 ------yangdk
#define DM9000_BASE 0x28000300
//#define DM9000_IRQ IRQ_EINT3
static struct resource s3c_dm9000_resource[] = {
[0] = {
.start = DM9000_BASE,
.end = DM9000_BASE+ 0x3,
.flags = IORESOURCE_MEM
},
[1]={
.start = DM9000_BASE + 0x4,
.end = DM9000_BASE + 0x4 + 0x7c,
.flags = IORESOURCE_MEM
},
[2] = {
.start = IRQ_EINT3,
.end = IRQ_EINT3,
.flags = IORESOURCE_IRQ
}
};
static struct dm9000_plat_data s3c_device_dm9000_platdata = {
.flags= DM9000_PLATF_16BITONLY,
};
struct platform_device s3c_device_dm9000 = {
.name= "dm9000",
.id= 0,
.num_resources= ARRAY_SIZE(s3c_dm9000_resource),
.resource= s3c_dm9000_resource,
.dev= {
.platform_data = &s3c_device_dm9000_platdata,
}
};
EXPORT_SYMBOL(s3c_device_dm9000);
//end of DM9000
//===========================================================================
2.在include/asm-arm/plat-s3c24xx/devs.h 文件中 添加一行
extern struct platform_device s3c_device_dm9000;
3.在arch/arm/mach-s3c2410/mach-smdk2410.c中將dm9000加入到要初始化的設備鏈表裏去,內核啓動時將會檢測設備並加載驅動
static struct platform_device *smdk2410_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
&s3c_device_dm9000,
};
4.在arch/arm/mach-s3c2440/mach-smdk2440.c中加入對DM9000的地址映射
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_CS2),
.length = 0x10000,
.type = MT_DEVICE,
}, {
.virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
.pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
.length = SZ_4M,
.type = MT_DEVICE,
}, {
.virtual = (u32)S3C24XX_VA_ISA_BYTE,
.pfn = __phys_to_pfn(S3C2410_CS2),
.length = 0x10000,
.type = MT_DEVICE,
}, {
.virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
.pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
.length = SZ_4M,
.type = MT_DEVICE,
},{
.virtual = S3C2410_ADDR(0x02100300),
.pfn = __phys_to_pfn(0x28000300), //DM9000 -----yangdk
.length = SZ_1M,
.type = MT_DEVICE,
}
};
5. 修改driver/net/dm9000.c
加入幾個頭文件,後面有用
view plaincopy to clipboardprint?
1. #i nclude
#i nclude
#i nclude 2. 在probe函數中加入 view plaincopy to clipboardprint? 1. unsigned char ne_def_eth_mac_addr[]={0x00,0x12,0x34,0x56,0x80,0x49};//yangdk 然後在大約640行(我的改動比較多,不記得原來的行號了)左右的地方修改 view plaincopy to clipboardprint? 1. for (i = 0; i < 6; i++) 2. //ndev->dev_addr[i] = ior(db, i+DM9000_PAR); //yangdk 3. ndev->dev_addr[i] = ne_def_eth_mac_addr[i]; 這是手動修改網卡的MAC地址,在上面的數組中自己隨便填入,不要是全0或者全1就行。 到此爲止,網卡可以發現了,也能配上IP,但是ping不同其他主機。是初始化的問題,繼續 6. 在probe函數中加入這部分代碼 view plaincopy to clipboardprint? 1. //-----------yangdk-------------------------------------------------> 2. 3. static void *bwscon,*bankcon4,*bankcon5; 4. static void *gpfcon,*gpfcon1; 5. static void *extint0,*extint01; 6. static void *intmsk; 7. static void *dsc0,*dsc1; 8. #define BWSCON (0x48000000) 9. #define BANKCON4 (0x48000014) 10. #define BANKCON5 (0x48000018) 11. #define GPFCON (0x56000060) //infact: GPGCON=0X56000060 12. #define GPFCON1 (0x56000050) 13. 14. #define EXTINT0 (0x5600008C) 15. #define EXTINT01 (0x56000088) 16. #define INTMSK (0x4A000008) 17. #define DSC0 0x560000c4) 18. #define DSC1 (0x560000c8) 19. 20. bwscon=ioremap_nocache(BWSCON,0x0000004); 21. extint01=ioremap_nocache(EXTINT01,0x0000004);// 22. 23. intmsk=ioremap_nocache(INTMSK,0x0000004); 24. dsc1=ioremap_nocache(DSC1,0x0000004); 25. 26. writel(readl(bwscon)|0xc0000,bwscon); 27. writel(readl(dsc1)|(0xf<<8),dsc1); 28. 29. s3c2410_gpio_cfgpin(S3C2410_GPF3, S3C2410_GPF3_EINT3); 30. writel((readl(extint01)&(~(3<<13)))|(1<<12),extint01); //eint3 high level 31. writel(readl(intmsk)&(~(1<<3)),intmsk); // 32. 33. 34. //<-----------yangdk------------------------------------------------ 這時啓動就OK了! (完)
#i nclude
#i nclude 2. 在probe函數中加入 view plaincopy to clipboardprint? 1. unsigned char ne_def_eth_mac_addr[]={0x00,0x12,0x34,0x56,0x80,0x49};//yangdk 然後在大約640行(我的改動比較多,不記得原來的行號了)左右的地方修改 view plaincopy to clipboardprint? 1. for (i = 0; i < 6; i++) 2. //ndev->dev_addr[i] = ior(db, i+DM9000_PAR); //yangdk 3. ndev->dev_addr[i] = ne_def_eth_mac_addr[i]; 這是手動修改網卡的MAC地址,在上面的數組中自己隨便填入,不要是全0或者全1就行。 到此爲止,網卡可以發現了,也能配上IP,但是ping不同其他主機。是初始化的問題,繼續 6. 在probe函數中加入這部分代碼 view plaincopy to clipboardprint? 1. //-----------yangdk-------------------------------------------------> 2. 3. static void *bwscon,*bankcon4,*bankcon5; 4. static void *gpfcon,*gpfcon1; 5. static void *extint0,*extint01; 6. static void *intmsk; 7. static void *dsc0,*dsc1; 8. #define BWSCON (0x48000000) 9. #define BANKCON4 (0x48000014) 10. #define BANKCON5 (0x48000018) 11. #define GPFCON (0x56000060) //infact: GPGCON=0X56000060 12. #define GPFCON1 (0x56000050) 13. 14. #define EXTINT0 (0x5600008C) 15. #define EXTINT01 (0x56000088) 16. #define INTMSK (0x4A000008) 17. #define DSC0 0x560000c4) 18. #define DSC1 (0x560000c8) 19. 20. bwscon=ioremap_nocache(BWSCON,0x0000004); 21. extint01=ioremap_nocache(EXTINT01,0x0000004);// 22. 23. intmsk=ioremap_nocache(INTMSK,0x0000004); 24. dsc1=ioremap_nocache(DSC1,0x0000004); 25. 26. writel(readl(bwscon)|0xc0000,bwscon); 27. writel(readl(dsc1)|(0xf<<8),dsc1); 28. 29. s3c2410_gpio_cfgpin(S3C2410_GPF3, S3C2410_GPF3_EINT3); 30. writel((readl(extint01)&(~(3<<13)))|(1<<12),extint01); //eint3 high level 31. writel(readl(intmsk)&(~(1<<3)),intmsk); // 32. 33. 34. //<-----------yangdk------------------------------------------------ 這時啓動就OK了! (完)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.