1. 程式人生 > >05-S3C2440學習之核心(移植)linux3.4.2移植(3)之支援DM9000C網絡卡及修改支援串列埠2

05-S3C2440學習之核心(移植)linux3.4.2移植(3)之支援DM9000C網絡卡及修改支援串列埠2

接下來我們在此基礎上,linux3.4.2中移植DM9000c網絡卡驅動,使核心可以支援網絡卡晶片,這樣方便使用NFS網路檔案系統。

一、移植思路

(1)我們現在移植好的核心中,支援smdk2440單板和mini2440單板。且使用mini2440機器id的時候,已經可以正常使用網路了。



因為mini2440的配置檔案中,包含了網絡卡的平臺驅動裝置。(arch/arm/mach-s3c24xx/Mach-mini2440.c)

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_ohci,
	&s3c_device_wdt,
	&s3c_device_i2c0,
	&s3c_device_rtc,
	&s3c_device_usbgadget,
	&mini2440_device_eth,
	&mini2440_led1,
	&mini2440_led2,
	&mini2440_led3,
	&mini2440_led4,
	&mini2440_button_device,
	&s3c_device_nand,
	&s3c_device_sdi,
	&s3c_device_iis,
	&uda1340_codec,
	&mini2440_audio,
	&samsung_asoc_dma,
};

(2)參考(arch/arm/mach-s3c24xx/Mach-mini2440.c)中網路平臺裝置的內容,拷貝修改到(arch/arm/mach-s3c24xx/Mach-smdk2440.c)

#include <linux/dm9000.h>

#define MACH_SMDK2440_DM9K_BASE (S3C2410_CS4 + 0x300)

/* DM9000AEP 10/100 ethernet controller */

static struct resource smdk2440_dm9k_resource[] = {
	[0] = {
		.start = MACH_SMDK2440_DM9K_BASE,
		.end   = MACH_SMDK2440_DM9K_BASE + 3,
		.flags = IORESOURCE_MEM
	},
	[1] = {
		.start = MACH_SMDK2440_DM9K_BASE + 4,
		.end   = MACH_SMDK2440_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 smdk2440_dm9k_pdata = {
	.flags		= (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
};

static struct platform_device smdk2440_device_eth = {
	.name		= "dm9000",
	.id		= -1,
	.num_resources	= ARRAY_SIZE(smdk2440_dm9k_resource),
	.resource	= smdk2440_dm9k_resource,
	.dev		= {
		.platform_data	= &smdk2440_dm9k_pdata,
	},
};


static struct platform_device *smdk2440_devices[] __initdata = {
	&s3c_device_ohci,
	&s3c_device_lcd,
	&s3c_device_wdt,
	&s3c_device_i2c0,
	&s3c_device_iis,
	&smdk2440_device_eth,
};

(3)編譯

make uImage

cp arch/arm/boot/uImage  /work/nfs_root/uImage_net

nfs 32000000  192.168.1.100:/work/nfs_root/uImage_net_net

bootm 32000000

ifconfig eth0 192.168.1.20

mount -t nfs  -o nolock 192.168.1.100:/work/nfs_root    /mnt 成功

二、移植新版本網絡卡驅動

(1)思路

之前我們在linux2.2.26上移植並製作好了網絡卡驅動。但是隨著linux版本的更新。一些庫函式在改變,有增加新用法,有減少等等,我們的網絡卡驅動編譯後已經無法直接通過,所以需要更加新版本核心的庫函式來修改已經的驅動,是它可以在新核心linux3.2.4下編譯通過。當然我們也可以找廠家索要更新的網絡卡驅動檔案,這樣會更好的支援新核心。

移植:

1. 編譯

2. 解決錯誤

2.1 標頭檔案不對:去掉或改名

2.2 巨集不對:改名使用新巨集

2.3 有些函式沒有了:改名使用新函式

(2)更新核心驅動檔案

通過以上修改後我們的驅動已經可以正常make,現在把新的DM9000C驅動放入核心中,覆蓋以前老版本的DM9000驅動。



nfs 32000000192.168.1.100:/work/nfs_root/uImage_net_new

nand erase.part kernel

nand write 32000000  kernel

mount -t nfs  -o nolock 192.168.1.100:/work/nfs_root    /mnt

核心啟動的時候設定IP,並掛載網路檔案系統:


到此,核心已經可以使用網絡卡傳輸資料了,可以掛載網路檔案系統。

三、思考:

我們看到核心中使用了platform平臺裝置驅動的方式在組織網絡卡驅動,其驅動部分是DM9000.C這部分是穩定不變的,變化的是我們dev資源部分。可見platform平臺的優勢。我們在檔案中添加了網絡卡裝置static struct platform_device smdk2440_device_eth ,在單板初始化函式smdk2440_machine_init中,執行了platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));將platform_device陣列中的裝置依次進行註冊。



四、修改核心支援串列埠2

核心啟動後,我們在終端中輸入 ls /dev  可以看到很多裝置節點,比如ttySAC0-2,對應了串列埠0、1、2。核心啟動為什麼就可以看到呢?是依賴檔案系統對mdev的載入,檔案系統預設載入mdev,而且/etc中也做了對mdev的相關操作。 移植好以上部分,我們的核心已經基本完整,但是在實驗中發現,串列埠2不能正常收發,但是串列埠0、1都是正常可以收發的,查詢原因是核心中對串列埠2的設定問題。 串列埠2預設工作在紅外模式,我們要將其設定為普通的串列埠,並初始化。 具體修改如下紅色部分: (1)修改串列埠2為普通模式: 修改linux-3.4.2/arch/arm/mach-s3c24xx/mach-smdk2440.c static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = {
[0] = {
.hwport     = 0,
.flags     = 0,
.ucon    = 0x3c5,
.ulcon     = 0x03,
.ufcon     = 0x51,
},
[1] = {
.hwport     = 1,
.flags     = 0,
.ucon    = 0x3c5,
.ulcon     = 0x03,
.ufcon     = 0x51,
},
/* IR port */
[2] = {
.hwport     = 2,
.flags     = 0,
.ucon    = 0x3c5,
//.ulcon     = 0x43,  修改為如下
.ulcon     = 0x03,

.ufcon    = 0x51,
}
};
(2)初始化串列埠2 修改/linux-3.4.2/drivers/tty/serial/samsung.c加入:

#include<linux/gpio.h>

#include<mach/regs-gpio.h>

以及:

dbg("s3c24xx_serial_startup ok\n");
/* the port reset code should have done the correct
* register setup for the port controls */ 
//新增
 if (port->line == 2) 
 {
  s3c2410_gpio_cfgpin(S3C2410_GPH(6), S3C2410_GPH6_TXD2);
  s3c2410_gpio_cfgpin(S3C2410_GPH(7), S3C2410_GPH7_RXD2);
 }

return ret;
 err:
s3c24xx_serial_shutdown(port);
return ret;
}