初识Linux Kernel 移植 之 dm9621网卡驱动移植

概述

将kernel移植到开发板并能正常加载和启动内核后,发现网卡并没有工作,因此将网卡作为第一个移植的实践。这篇文章用于记录移植dm9621网卡过程中遇到的问题以及如何定位问题并尝试解决。

配置内核

在找到dm9621网卡驱动的源码后,需要将其添加到内核,并编译到内核去不采用动态加载模块,需要做哪些修改呢?这需要通过内核配置菜单来配置,将dm9620.c(dm9621 网卡驱动源码)拷贝到 driver/net/usb 目录下,通过配置该目录下Kconfig 和 Makefile 来决定。

//Kconfig 添加(添加dm9620 编译选项):
+config USB_NET_DM9620
+   tristate "Davicom DM9620/21 based USB 2.0 10/100 ethernet devices"
+    depends on USB_USBNET
+    select CRC32
+   help
+       This option adds support for Davicom DM9620 based USB 2.0
+      10/100 Ethernet adapters.
+
+     This driver creates an interface named "ethX",where X depends on
+      what other networking devices you have in use.
+
+      To compile this driver as a module.choose M here.

//Makefile 添加(CONFIG_USB_NET_DM9620 为 y时编译进内核,为 M 时编译成模块):
+ obj-$(CONFIG_USB_NET_DM9620)    += dm9620.o  

添加好之后就可以通过 make menuconfig来配置了,由于dm9621是usb类型网卡,因此需要依赖于usb 网络框架:

Device Drivers  --->   
     [*] Network device support  ---> 
               USB Network Adapters  ---> 
                   <*> Multi-purpose USB Networking Framework
                     <*>   Davicom DM9620/21 based USB 2.0 10/100 ethernet devices

dm9621 网卡驱动编译配置选项

dm9621 网卡驱动编译配置选项

问题探索

读 dm9621 MAC 地址失败

在kernel的启动信息中可以看到dm9620 相关的启动信息中有这样一条信息:

(unregistered net_device): Error reading MAC address

这信息来源在 调用usbnet_probe()函数(usbnet.c)中调用bind函数时读取MAC地址失败,目标网卡设备未注册。通过添加调试来排查dm9620驱动注册是否成功,下面是dm9620驱动注册过程中函数调用关系:

usb_register()    // module_init(usb_register)
    usb_register_driver()    // 注册一个 USB interface 驱动
        driver_register()    // 总线型驱动注册(dm9620 是usb类型)
            bus_add_driver()    // 将驱动添加到总线(将dm9620驱动添加到usb总线)
                driver_attach()    // 将驱动绑定到设备
                    bus_for_each_dev()    // 设备迭代器,查找所有的设备,并调用回调函数
                        __driver_attach()    // 绑定查找到的设备
                          driver_match_device()    // 实现驱动和设备的匹配工作
                          driver_probe_device()    // 如果匹配成功会调用该函数,将设备和驱动进行绑定

通过添加调试信息,在执行调用driver_match_device函数后会由于匹配dm9620驱动和设备失败返回,而不调用driver_probe_device函数进行设备和驱动的绑定。分析到这就猜测是不是设备的问题,通过使用lsusb命令,发现并没有dm9621 的usb网卡设备,因此推测应该是网卡设备没有被发现导致注册失败。而这个网卡设备是通过usb3503A hub连接到开发板的,在使用lsusb命令时同样没有发现3053 usb设备,因此呢这个usb设备也没有被发现。通过查看usb3503A 的初始化操作,发现原代码使用的GPIO引脚并非板子上usb3503 链接的引脚,因此需要修改usb3503A 的reset 和 connect 引脚:

// 位于板子配置初始化文件中 arch/arm/mach-exynos/mach-smdk4x12.c
// usb_hub_gpio_init() 对usb3503 引脚进行初始化
- #define GPIO_HUB_RESET EXYNOS4_GPL2(2)
- #define GPIO_HUB_CONNECT EXYNOS4_GPK3(2)
+ #define GPIO_HUB_RESET EXYNOS4212_GPM2(4)
+ #define GPIO_HUB_CONNECT EXYNOS4212_GPM3(3)

通过修改上面的修改,重新编译加载内核后,再次使用lsusb命令,可以查看到已经发现了usb3503 和 dm9621 设备:
在这里插入图片描述

网卡反复断开重连

通过之前的修改,虽然已经发现了网卡设备,但是发现网卡设备会发生2~3次的被发现和断开,下面是kernel中dm9620驱动相关的启动信息:
在这里插入图片描述
这是怎么回事呢?这种现象很像是多次插拔了usb网卡,通过开发板的原理图发现,dm9621 的RSTB引脚是链接到4412芯片的GPC0_1 引脚,猜测可能该引脚被多次的配置,因为将这个引脚拉低会初始化dm9621 ,因此会造成这种类似的现象。通过搜索,发现GPC0_1 在原码中被当成其他引脚功能使用,因此将这些使用了该引脚代码注释掉(在s3c-fb.c 和setup-fb-s5p.c中引用,原因是暂时还没找到这些原码应该使用哪个才是正确的引脚)。同时在板级初始化函数中添加对dm9621的初始化:

static void __init smdk4x12_machine_init(void)
{
……
+ #ifdef CONFIG_USB_NET_DM9620
+	dm9620_reset();
+ #endif
}
+ #ifdef CONFIG_USB_NET_DM9620
+ static void __init dm9620_reset(void)
+ {
+	int err = 0;

+	err = gpio_request_one(EXYNOS4_GPC0(1), GPIOF_OUT_INIT_HIGH, "DM9620_RESET");
+	if (err)
+		pr_err("failed to request GPC0_1 for DM9620 reset control\n");

+	s3c_gpio_setpull(EXYNOS4_GPC0(1), S3C_GPIO_PULL_UP);
+	gpio_set_value(EXYNOS4_GPC0(1), 0);
	
+	mdelay(1000); //dg change 5 ms to 1000ms for test dm9620 

+	gpio_set_value(EXYNOS4_GPC0(1), 1);
+	gpio_free(EXYNOS4_GPC0(1));
+}
+ #endif
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
linux移植驱动编写最详细教程,Linux 操作系统的安装以及配置............................................................................................3 1 如何安装RedHat9.0 ................................................................................................3 2 在RedHat 中添加新用户.......................................................................................16 3 配置PC 机Linux 的ftp 服务...................................................................................16 4 配置PC 机Linux 的telnet .....................................................................................17 5 建立交叉编译环境...................................................................................................17 6 编译内核..................................................................................................................17 Linux移植.......................................................................................................................19 1 Bootloader 的移植.................................................................................................19 1.1 vivi 的配置与编译..........................................................................................19 1.2 配置和编译vivi .............................................................................................20 1.3 vivi 代码分析..................................................................................................21 1.4 vivi 的运行.....................................................................................................21 1.5 启动代码执行流程图.....................................................................................45 1.6 vivi 的配置文件..............................................................................................45 2 Linux 内核

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值