12. 移植DM9000网卡驱动到Linux-4.15内核
12.1 移植步骤
(1) 编译
(2) 解决错误
(2.1)头文件不对:去掉或改名
(2.2)宏不对:改名使用新宏
(2.2)有些函数没有了:改名使用新函数
12.2 移植内核自带的网卡驱动程序
12.2.1 参考mini2440如何支持DM9000网卡
在dm9000的驱动程序中,有如下结构体:(在drivers/net/ethernet/davicom/dm9000.c)
static struct platform_driver dm9000_driver = {
.driver = {
.name = "dm9000",
.pm = &dm9000_drv_pm_ops,
.of_match_table = of_match_ptr(dm9000_of_matches),
},
.probe = dm9000_probe,
.remove = dm9000_drv_remove,
};
一般是通过 .name 这个成员进行匹配的,搜索字符串"dm9000",找到如下结构体:(在arch/arm/mach-s3c24xx/mach-mini2440.c)
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,
},
};
然后在该文件中搜索结构体mini2440_device_eth,找到:
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,
&s3c2440_device_dma,
&s3c_device_iis,
&uda1340_codec,
&mini2440_audio,
};
然后再搜索mini2440_devices,在mini2440_init函数中可以找到:
platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));
这就是把结构体mini2440_devices添加到内核,里面的关于网卡的结构在里面,最终匹配驱动程序,就可以使用驱动程序了。
12.2.2 添加代码使smdk2440支持DM9000网卡
(1) 前面mini2440支持dm9000网卡的代码所做的事情:① 添加 dm9000 网卡平台设备;② 把 dm9000网卡驱动程序添加到内核;
(2) 接下来就是在arch/arm/mach-s3c24xx/mach-smdk2440.c添加dm9000网卡相关代码:
① 添加dm9000 网卡平台设备:
/*
* The DM9000 has no eeprom, and it's MAC address is set by
* the bootloader before starting the kernel.
*/
/* DM9000AEP 10/100 ethernet controller */
#define MACH_SMDK2440_DM9K_BASE (S3C2410_CS4 + 0x300)
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,
}
};
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,
},
};
② 把 dm9000网卡驱动程序添加到内核,在结构体smdk2440_devices中添加网卡成员:
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, /* 添加 */
};
同时需要添加dm9000.h头文件:#include <linux/dm9000.h>
③ 然后重新编译内核,成功。设置机器id,烧写新内核:
set machid 16a
save
nfs 30000000 192.168.0.106:/home/book/works/first_fs/uImage_new
nand erase.part kernel
nand write 30000000 kernel $filesize
12.3 测试
(1) 重启开发开发板,输入命令:ifconfig,打印信息如下:
可见,dm9000网卡已成功配置了ip地址、MAC地址、掩码等。(启动时etc/init.d/rcS 文件执行了命令:ifconfig eth0 192.168.0.200
)
(2) ping测试,输入命令:ping 192.168.0.106
(ubuntu 服务器IP地址),打印信息如下:
可以,ping测试成功。
(3) mount 挂载文件夹测试,输入命令:mount -t nfs -o nolock,vers=2 192.168.0.106:/home/book/works/first_fs/ /mnt
,打印信息如下:
(把ubuntu服务的文件夹 /home/book/works/first_fs/ 挂载到 /mnt目录下)
综上所述:smdk2440成功支持dm9000网卡。