以太网驱动的流程浅析(一)-Ifconfig主要流程【原创】
以太网驱动的流程浅析(一)-Ifconfig主要流程
Author:张昺华
Email:920052390@qq.com
Time:2019年3月23日星期六
此文也在我的个人公众号以及《Linux内核之旅》上有发表:以太网驱动流程浅析(一)-ifconfig主要流程
大家好,我叫张昺华,中间那个字和“饼”字一个读音。
2014年我毕业于广东省惠州学院,我从小酷爱理科,当看到陈莉君老师在《Linux内核之旅》上发的学生在课堂上用课本剧的方式来诠释技术时,想到了自己初中的时候老师就是这样锻炼我们的,很喜欢那样的学习氛围,自己大学时和小伙伴们一起创立了科技创新协会,目的就是可以一群人在研究技术,一起做有意思的东西,一起分享技术带给我们的快乐,也希望中国有更多的人热爱技术,喜欢一起研究、分享技术,然后可以一起用我们的技术来做一些好玩的东西,可以为这个社会创造一些东西来改善人们的生活。
如下是本人调试过程中的一点经验分享,以太网驱动架构毕竟涉及的东西太多,如下仅仅是针对加载流程和围绕这个问题产生的分析过程和驱动加载流程部分,并不涉及以太网协议层的数据流程分析。
【硬件环境】 Imx6ul
【Linux kernel版本】 Linux4.1.15
【以太网phy】 Realtek8201f
一个以太网的案例来讲述Ifconfig
1. 问题描述
【问题】
机器通过usb方式下载了mac地址后,发现以太网无法正常使用,敲命令 ifconfig eth0 up出现:ifconfig: SIOCSIFFLAGS: No such device,而对于没有下载以太网mac address的机器表现均正常。调试过程中发现在以太网控制器代码中加入一些printk,不正常的机器又正常了,打印的位置不同,机器的以太网有时会正常,有时会异常,十分诡异。
2. 原因分析
【根本原因】
reset时序问题导致,phy reset的时间不满足时序要求。如下图,如果硬件接了reset引脚,应满足时序要求在reset保持10ms有效电平后,还必须维持至少150ms才可以访问phy register,也就是reset要在B点之后才可以正常通过MDC/MDIO来访问phy register。如果是不使用硬件reset,使用软件reset方式,那也要至少在A点,也就是在reset维持10ms有效电平后,再维持3.5个clk才能正常访问phy register。
那为什么下载了mac地址后才异常呢?不下载的又正常呢?
【原因分析】
freescale控制器获取mac address流程如下:
1)模块化参数设置,如果没有跳到步骤2;
2)device tree中设置,如果没有跳到步骤3;
3)from flash / fuse / via platform data,如果没有跳到步骤4;
4)FEC mac registers set by bootloader===》即靠usb方式下载mac address ,如果没有跳到步骤5;
5)靠kernel算一个随机数mac address出来,然后写入mac
那为什么下载了mac地址后才异常呢?
下了mac后,会执行步骤4,不会执行步骤5,此时目前的代码不满足150ms的时序要求,无法访问phy register,
导致phy_id获取不到,因此phy_device也不会创建
那为什么不下载的又正常呢?
不下载mac address,会执行步骤5 ,步骤5中调用了函数eth_hw_addr_random
刚好满足了150ms的时序要求,所以才可以正常
跟入代码eth_hw_addr_random看下
继续看:
最终调用了kernel提供的获取随机数的一个函数,这块代码比较多就不继续追下去了。
所以这块步骤五的代码刚刚好好在这个硬件条件下,恰巧满足了150ms的reset时序要求,所以以太网才可以正常。
3. 以太网流程分析跟踪
3.1 Ifconfig主要流程
回归主题,根据这个ifconfig失败的现象,我们追踪一下code:
ifconfig: SIOCSIFFLAGS: No such device,既然出现了这个问题log,我们就从应用层的log入手,首先我们使用strace命令来追踪下系统调用,以便于我们追踪内核代码实现。
strace ifconfig eth0 up跟踪一下
可以发现主要是ioctl的操作,SIOCSIFFLAGS,然后我们需要了解下这个宏的意思,说白了就是设置各种flag,靠ioctl第三个参数把所需要的动作flag传入,比如说此时要对eth0进行up动作,那么就传入IFF_UP,例如:
struct ifreq ifr;
我们看这些主要是想知道为什么会打印这个log:
ifconfig: SIOCSIFFLAGS: No such device
那么内核中又是对ioctl做了什么动作呢?因为strace命令让我们知道了系统调用调用函数,我们可以在kernel中直接搜索SIOCSIFFLAGS,或者去以太网驱动net目录下直接搜索更快。最终我搜到了,路径是:net/ipv4/devinet.c
我们可以看到内核的宏定义:
查看devinet.c的代码,我们找到了那个宏,也就是做devinet_ioctl函数中,这也就是应用层的ioctl最终的实现函数,然后我们在里面加一些打印,
通过打印结果我们可以确认是这个函数devinet_ioctl为应用层的ioctl的实现函数,因为你在kernel中搜SIOCSIFFLAGS宏的话会有很多地方出现的,所以我们需要确认我们找的函数
没问题:
看到这里返回值ret是-19,那么我们继续顺着追踪下去,上代码:
net/core/dev.c
继续追踪:net/core/dev.c
因此我们可以看到返回值-19就是如下代码产生的
因此我们需要追踪__dev_open函数,继续看代码:
通过调试,比如说加打印,或者是经验我们可以推断出是这里返回的-19,那么这个ndo_open又是在哪里回调的呢?
我们可以看到ops这个结构的结构体
struct net_device dev
const struct net_device_ops ops = dev->netdev_ops;
这里熟悉驱动的朋友应该可以猜到这在在freescale的以太网控制器驱动中一定有它的实现
net_device_ops就是kernel提供给drvier操作net_device的一些操作方法,具体实现自然由相应厂商的driver自己去实现。
路径:drivers/net/Ethernet/freescale/fec_main.c
我们可以在这个fec_enet_open函数中加入dump_stack来看下整个调用情况
我们打出kernel的dump_stack信息来看:
这个调用过程就是应用层ioctl一直到kernel最底层fec_enet_open的过程。
应用代码这样:
总体流程:kill() -> kill.S -> swi陷入内核态 -> 从sys_call_table查看到sys_kill -> ret_fast_syscall -> 回到用户态执行kill()下一行代码
Ioctl《==ret_fast_syscall 《==SyS_ioctl《==do_vfs_ioctl《==vfs_ioctl《==sock_ioctl《==
devinet_ioctl《==dev_change_flags《==__dev_change_flags《==__dev_open《==fec_enet_open
我附上每个函数的代码:
如果大家想看系统调用流程的话,参考这篇,我就不做这块的说明了:
Linux系统调用(syscall)原理
http://gityuan.com/2016/05/21/syscall/
Arm Linux系统调用流程详细解析
https://www.cnblogs.com/cslunatic/p/3655970.html
4. 网址分享
http://stackoverflow.com/questions/5308090/set-ip-address-using-siocsifaddr-ioctl
http://www.ibm.com/support/knowledgecenter/ssw_aix_72/com.ibm.aix.commtrf2/ioctl_socket_control_operations.htm
https://lkml.org/lkml/2017/2/3/396
linux PHY驱动
http://www.latelee.org/programming-under-linux/linux-phy-driver.html
Linux PHY几个状态的跟踪
http://www.latelee.org/programming-under-linux/linux-phy-state.html
第十六章PHY -基于Linux3.10
https://blog.csdn.net/shichaog/article/details/44682931
```
End
以太网驱动的流程浅析(一)-Ifconfig主要流程【原创】的更多相关文章
- 以太网驱动的流程浅析(三)-ifconfig的-19错误最底层分析【原创】
以太网驱动流程浅析(三)-ifconfig的-19错误最底层分析 Author:张昺华 Email:920052390@qq.com Time:2019年3月23日星期六 此文也在我的个人公众号以及& ...
- 以太网驱动的流程浅析(二)-Ifconfig的详细代码流程【原创】
以太网驱动流程浅析(二)-ifconfig的详细代码流程 Author:张昺华 Email:920052390@qq.com Time:2019年3月23日星期六 此文也在我的个人公众号以及<L ...
- Android 4.4 Kitkat Phone工作流程浅析(六)__InCallActivity显示更新流程
本文来自http://blog.csdn.net/yihongyuelan 转载请务必注明出处 本文代码以MTK平台Android 4.4为分析对象,与Google原生AOSP有些许差异,请读者知悉. ...
- Android 4.4 Kitkat Phone工作流程浅析(八)__Phone状态分析
本文来自http://blog.csdn.net/yihongyuelan 转载请务必注明出处 本文代码以MTK平台Android 4.4为分析对象.与Google原生AOSP有些许差异.请读者知悉. ...
- Android 4.4 Kitkat Phone工作流程浅析(七)__来电(MT)响铃流程
本文来自http://blog.csdn.net/yihongyuelan 转载请务必注明出处 本文代码以MTK平台Android 4.4为分析对象,与Google原生AOSP有些许差异,请读者知悉. ...
- 以太网驱动的流程浅析(四)-以太网驱动probe流程【原创】
以太网驱动的流程浅析(四)-以太网驱动probe流程 Author:张昺华 Email:920052390@qq.com Time:2019年3月23日星期六 此文也在我的个人公众号以及<Lin ...
- 以太网驱动的流程浅析(五)-mii_bus初始化以及phy id的获取【原创】
以太网驱动的流程浅析(五)-mii_bus初始化以及phy id的获取 Author:张昺华 Email:920052390@qq.com Time:2019年3月23日星期六 此文也在我的个人公众号 ...
- 玩转Windows服务系列——服务运行、停止流程浅析
通过研究Windows服务注册卸载的原理,感觉它并没有什么特别复杂的东西,Windows服务正在一步步退去它那神秘的面纱,至于是不是美女,大家可要睁大眼睛看清楚了. 接下来研究一下Windows服务的 ...
- 玩转Windows服务系列——服务运行、停止流程浅析
原文:玩转Windows服务系列——服务运行.停止流程浅析 通过研究Windows服务注册卸载的原理,感觉它并没有什么特别复杂的东西,Windows服务正在一步步退去它那神秘的面纱,至于是不是美女,大 ...
随机推荐
- Azure EventHub快速入门和使用心得
Azure Event Hubs(事件中心)是一个大数据流式数据摄取服务平台,每秒接受数百万事件; EventHubs 是一个有数据保留期限的缓冲区,类似分布式日志:可缩放的关键在于[分区消费模型], ...
- 百万年薪python之路 -- 带颜色的print
带颜色的print print输出带颜色的方法详解 书写格式: 开头部分:\033[显示方式;前景色;背景色m + 结尾部分:\033[0m 注意:开头部分的三个参数:显示方式,前景色,背景色是可 ...
- spring boot 日志收集整理
spring boot 日志 1. 选择那种日志框架 slf4j 是抽像的接口层.也是spring boot 默认采用的接口层. util.logging,log4j,logback,commons- ...
- SpringBoot学习(二)探究Springboot启动机制
引言: SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说,如果不大懂SpringBoot内部启动原理,以后难免会吃亏.所以这次博主就跟你们一起探究一下SpringBoot的启动原 ...
- EFCore--->> CodeFirst (Vs2019 Core3.0)的简单使用
直接上干货 EFCore--->> CodeFirst (Vs2019 Core3.0) 1: 安装下面3个对应的package(在Nuget控制台或者直接NuGet包查询点击下载,我喜欢 ...
- OptimalSolution(5)--数组和矩阵问题(1)简单
一.转圈打印矩阵 题目:给定一个整型矩阵matrix,按照转圈的方式打印它. 要求:额外空间复杂度为O(1) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 打印结果为: ...
- jquery复习
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Spring中@Resource注解报错
描述:Spring框架中,@Resource注解报错,在书写时没有自动提示 解决方法:因为maven配置文件的pom.xml文件中缺少javax.annotation的依赖,在pom.项目路中加入依赖 ...
- 匹马行天下之思维决定高度篇——道道道,学习Java之道
致Java星球的程序员兄弟们的一封信 亲爱的Java星球的程序员兄弟们: 你们好!我是来自地球的一名Java程序员,首先我代表地球人对贵星球的高司令来到地球传授Java语言,造福了全人类,造福了整个地 ...
- JNI技术实现--Java调C/C++
废话不多说,首先我们来看Java调用C/C++步骤: 1.编写Java代码,在代码中使用native关键字标明该方法是调用本地库,不需要实现. 2.使用javah -jni 命令,生成对应的头文件,此 ...
























