05-S3C2440学习之内核(移植)linux3.4.2移植(3)之支持DM9000C网卡及修改支持串口2

版权声明:如需交流讨论,请关注微信公众号:【柒零玖嵌入式】留言。本文为博主原创文章,转载请注明 https://blog.csdn.net/fengyuwuzu0519/article/details/72846205

之前我们裁剪并移植好了linux3.4.2内核     http://blog.csdn.net/fengyuwuzu0519/article/details/70162666

也学习过 移植DM9000C网卡驱动程序到linux2.2.26内核上http://blog.csdn.net/fengyuwuzu0519/article/details/72821567

接下来我们在此基础上,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;
}
展开阅读全文

没有更多推荐了,返回首页