以太网驱动的流程浅析(一)-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主要流程【原创】的更多相关文章

  1. 以太网驱动的流程浅析(三)-ifconfig的-19错误最底层分析【原创】

    以太网驱动流程浅析(三)-ifconfig的-19错误最底层分析 Author:张昺华 Email:920052390@qq.com Time:2019年3月23日星期六 此文也在我的个人公众号以及& ...

  2. 以太网驱动的流程浅析(二)-Ifconfig的详细代码流程【原创】

    以太网驱动流程浅析(二)-ifconfig的详细代码流程 Author:张昺华 Email:920052390@qq.com Time:2019年3月23日星期六 此文也在我的个人公众号以及<L ...

  3. Android 4.4 Kitkat Phone工作流程浅析(六)__InCallActivity显示更新流程

    本文来自http://blog.csdn.net/yihongyuelan 转载请务必注明出处 本文代码以MTK平台Android 4.4为分析对象,与Google原生AOSP有些许差异,请读者知悉. ...

  4. Android 4.4 Kitkat Phone工作流程浅析(八)__Phone状态分析

    本文来自http://blog.csdn.net/yihongyuelan 转载请务必注明出处 本文代码以MTK平台Android 4.4为分析对象.与Google原生AOSP有些许差异.请读者知悉. ...

  5. Android 4.4 Kitkat Phone工作流程浅析(七)__来电(MT)响铃流程

    本文来自http://blog.csdn.net/yihongyuelan 转载请务必注明出处 本文代码以MTK平台Android 4.4为分析对象,与Google原生AOSP有些许差异,请读者知悉. ...

  6. 以太网驱动的流程浅析(四)-以太网驱动probe流程【原创】

    以太网驱动的流程浅析(四)-以太网驱动probe流程 Author:张昺华 Email:920052390@qq.com Time:2019年3月23日星期六 此文也在我的个人公众号以及<Lin ...

  7. 以太网驱动的流程浅析(五)-mii_bus初始化以及phy id的获取【原创】

    以太网驱动的流程浅析(五)-mii_bus初始化以及phy id的获取 Author:张昺华 Email:920052390@qq.com Time:2019年3月23日星期六 此文也在我的个人公众号 ...

  8. 玩转Windows服务系列——服务运行、停止流程浅析

    通过研究Windows服务注册卸载的原理,感觉它并没有什么特别复杂的东西,Windows服务正在一步步退去它那神秘的面纱,至于是不是美女,大家可要睁大眼睛看清楚了. 接下来研究一下Windows服务的 ...

  9. 玩转Windows服务系列——服务运行、停止流程浅析

    原文:玩转Windows服务系列——服务运行.停止流程浅析 通过研究Windows服务注册卸载的原理,感觉它并没有什么特别复杂的东西,Windows服务正在一步步退去它那神秘的面纱,至于是不是美女,大 ...

随机推荐

  1. Spring使用AspectJ开发AOP:基于XML

    基于XML的声明式 基于 XML 的声明式是指通过 Spring 配置文件的方式定义切面.切入点及声明通知,而所有的切面和通知都必须定义在 <aop:config> 元素中. 下面通过案例 ...

  2. 基础安全术语科普(六)——exploit

    exploit (漏洞利用) 利用漏洞存在两种攻击形式: 1.Remote(远程):利用系统漏洞来获得访问权限. 2.local(本地):需要对系统进行物理访问来实现攻击. 如何发现漏洞? 利用逆向工 ...

  3. C++两个队列实现一个栈

    C++两个队列实现一个栈 /* * source.cpp * * Created on: 2015年6月21日 * Author: codekiller */ #include "iostr ...

  4. redis入门(二)

    目录 redis入门(二) 前言 持久化 RDB AOF 持久化文件加载 高可用 哨兵 流程 安装部署 配置技巧 集群 原理 集群搭建 参考文档 redis入门(二) 前言 在redis入门(一)简单 ...

  5. unity 开启外部摄像头

    在unity中建立一个image作为摄像头显示画面,然后通过命令render到image上即可. public WebCamTexture webTex; public string deviceNa ...

  6. 《JavaScript设计模式与开发实践》-- 策略模式

    详情个人博客:https://shengchangwei.github.io/js-shejimoshi-celue/ 策略模式 1.定义 策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们 ...

  7. JavaSE常用API

    1.Math.round(11.5)等于多少?Math.round(-11.5)又等于多少? Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11.四舍五 ...

  8. Codeforces 1109D: generalizations of Cayley's formula证明

    做这题的时候发现题解里有提到\(generalizations\ of\ Cayley's\ formula\)的,当场懵逼,Wikipedia里也就带到了一下,没有解释怎么来的,然后下面贴了篇论文. ...

  9. [考试反思]0816NOIP模拟测试23

    210 210 210 170 还可以.暴力打满就rk4了? 但不管怎么说,总算是在改完题之后理直气壮的写考试反思了. T1是个dp,说水也不太水.(当然某脸只要A掉了一道题就要说那是水题) 我的思路 ...

  10. javascript 作用域链及性能优化

    在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象.函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性.其中一个内部属 ...