以太网 MAC(链路层)+PHY(物理层/RTL8201F,88E1111);集成型DM9000,RTL8139CP 由于网络数据传输量较大,不论是分开型还是集成型,通常会在MAC和PHY之间引入DMA,MAC和PHY之所以有分开,是因为MAC属于数字电路部分,而PHY则属于模拟部分,负责将接收到的数据传输给MAC层,MAC层将接收到的数据传输给上层协议,如IP层,IGMP层。PHY层也负责将由MAC层发送过来的数据,转换成差分信号,经过后边的变压器后送入RJ45接头的线缆中。 对应的数据格式为: 前导符+开始位+目的MAC地址+源MAC地址+类型长度+数据+padding(optional)+32bit CRC PHY层负责的任务还是比较多的,比如10M/100M速率的选择;全双工还是半双工;载波侦听和冲突检测,这些工作对应到具体芯片就是内部寄存器的一些设置。 PHY功能模块和MCU的链接采用MII/RMII方式链接,这样就可以使用MCU设置相关的寄存器。MII是16根线,RMII将收发数据线各减到两根,这其中涉及串并转换,即将MCU的类的并行总线最终转换成RJ45线上传输的单bit编码。100M是曼彻斯特编码,10M是NRZ编码,这类编码主要考虑负载均衡和纠错。也带来了额外的网络开销。 PHY层的初始化,主要是两个部分,一个是mdio总线的初始化,一个是PHY驱动初始化,对于通常可以使用缺省内核的PHY驱动程序,但是如果PHY芯片的内部寄存器和802.3定义的并不一样,这就需要自己实现该驱动,像8201这样的百兆速率PHY芯片就可以使用缺省的PHY驱动,但是对于一些功能强一点的集成多个PHY的switch而言,通常驱动可能需要自己实现,switch常用来更高速率传输的或者VLAN这种网络。 PHY层从driver/net/phy/phy_device.c文件开始。 subsys_initcall(phy_init); module_exit(phy_exit); 又见subsys_initcall,该调用表明其在系统初始化时完成, static int __init phy_init(void) { int rc; rc = mdio_bus_init(); if (rc) return rc; rc = phy_driver_register(&genphy_driver); if (rc) mdio_bus_exit(); return rc; }。 其驱动涉及如下几个重要部分: 总线- sturct mii_bus (mii stand for media independent interface) 设备- struct phy_device 驱动- struct phy_driver mdiobus_register ------probe函数会调用,创建该总线,总线然后扫描其上面的设备,如果发现有,则创建该设备。 _|_ drovers\net\phy\mdio_bus.c drivers\net\phy\phy_device.c struct phy_device *mdiobus_scan(struct mii_bus * bus, int addr) ----get_phy_device--phy_device_create | | drivers\base\Core.c ----device_register---device_add(kobject_add构建设备树) 驱动会调用phy_driver_register去注册驱动,这是phy驱动也会形成一个链表,这里之所以不是树而上面的设备成为树,是因为 mii可能挂载在pci总线上,当然pci上可能有其它设备,这些设备和phy设备不在一个链表上,而是通过kobject链接管理的,对应的还有 一个kset,kset其实是kobject的一个集合,相同的kobject对象会指向同一个kset,如USB鼠标、键盘就属于同一个kset集。 上述的总线,设备,以及驱动(假设驱动已经编写好了,驱动中多半会有一个标示符,暂且将其看作为id,这个id指明了其支持的设备)内; 假设不支持热插拔,那么启动时,系统就会扫描设备,并串联进设备树,当驱动注册(register时),驱动就会去设备树中,找id号和其对 应的相等的,如果找到,那么这两个就捆绑在一起了,通常为XXX_attcah函数,应用层对该设备的操作就变为调用驱动中对应的read、write、 ioctl等。如果支持热插拔,比上面的就复杂了,因为驱动可能先于设备(总线)存在,所以当有新硬件连接时,内核会调用XXX_probe函数去 探测,并注册设备,然后去驱动链表中查找驱动,如果找到,则attach。对其操作方法与上述一样。 剩下一个问题就是驱动的编写了。

PHY Linux 驱动的更多相关文章

  1. linux驱动启动顺序

    首先,我们可以查看Linux内核编译完成后的System.map文件,在这个文件中我们可以看到macb(dm9161驱动模块)链接到了dm9000驱动之前,如下所示: c03b6d40 t __ini ...

  2. Linux 驱动框架---net驱动框架

    这一篇主要是学习网络设备驱动框架性的东西具体的实例分析可以参考Linux 驱动框架---dm9000分析 .Linux 对于网络设备的驱动的定义分了四层分别是网络接口层对上是IP,ARP等网络协议,因 ...

  3. Linux代码的重用与强行卸载Linux驱动

    (一)Linux代码的重用 重用=静态重用(将要重用的代码放到其他的文件的头文件中声明)+动态重用(使用另外一个Linux驱动中的资源,例如函数.变量.宏等) 1.编译是由多个文件组成的Linux驱动 ...

  4. Linux驱动学习之常用的模块操作命令

    1.常用的模块操作命令 (1)lsmod(list module,将模块列表显示),功能是打印出当前内核中已经安装的模块列表 (2)insmod(install module,安装模块),功能是向当前 ...

  5. Linux驱动学习之驱动开发准备工作

    一.开启驱动开发之路 1.驱动开发的准备工作 (1)正常运行linux系统的开发板.要求开发板中的linux的zImage必须是自己编译的,不能是别人编译的.原因在于在安装模块的时候会进行安全性校验 ...

  6. Linux驱动学习之什么是驱动?

    一.什么是驱动? 1: 驱动一词的字面意思 2: 物理上的驱动 3: 硬件中的驱动 4: linux内核驱动.软件层面上的驱动广义上是指:这一段代码操作了硬件去动,所以这一段代码就叫硬件的驱动程序. ...

  7. 嵌入式Linux驱动开发日记

    嵌入式Linux驱动开发日记 主机硬件环境 开发机:虚拟机Ubuntu12.04 内存: 1G 硬盘:80GB 目标板硬件环境 CPU: SP5V210 (开发板:QT210) SDRAM: 512M ...

  8. linux驱动程序设计的硬件基础,王明学learn

    linux驱动程序设计的硬件基础(一) 本章讲总结学习linux设备程序设计的硬件基础. 一.处理器 1.1通用处理器 通用处理器(GPP)并不针对特定的应用领域进行体系结构和指令集的优化,它们具有一 ...

  9. linux驱动初探之杂项设备(控制两个GPIO口)

    关键字:linux驱动.杂项设备.GPIO 此驱动程序控制了外接的两个二极管,二极管是低电平有效. 上一篇博客中已经介绍了linux驱动程序的编写流程,这篇博客算是前一篇的提高篇,也是下一篇博客(JN ...

随机推荐

  1. SQL Server中使用自定义指定顺序排序

    比如需要对SQL表中的字段NAME进行如下的排序:张三(Z)李四(L)王五(W)赵六(Z) 如果想按 “ 张三.李四.王五.赵六”的顺序排序,则可以使用以下语句: order by charindex ...

  2. QT创建模态对话框阻塞整个应用程序和非模态对话框唯一性约束的简单示例

    QT创建模态对话框阻塞整个应用程序和非模态对话框唯一性约束的简单示例 部分代码: // 创建模态对话框阻塞整个应用程序和非模态对话框唯一性约束 QMenu *pDialog = mBar->ad ...

  3. React Native工程中TSLint静态检查工具的探索之路

    建立的代码规范没人遵守,项目中遍地风格迥异的代码,你会不会抓狂? 通过测试用例的程序还会出现Bug,而原因仅仅是自己犯下的低级错误,你会不会抓狂? 某种代码写法存在问题导致崩溃时,只能全工程检查代码, ...

  4. 信息收集利器——Nmap

    环境:kali2.0 常用的Nmap命令总结: 1.扫描单个IP地址 nmap 192.168.56.1 2.扫描一个网络中IP地址范围 nmap 192.168.56.1-255 3.扫描目标主机的 ...

  5. 洛谷 P2659 美丽的序列 解题报告

    P2659 美丽的序列 题目背景 GD是一个热衷于寻求美好事物的人,一天他拿到了一个美丽的序列. 题目描述 为了研究这个序列的美丽程度,GD定义了一个序列的"美丽度"和" ...

  6. windows内核提权

    Windows by default are vulnerable to several vulnerabilities that could allow an attacker to execute ...

  7. Codeforces 585D. Lizard Era: Beginning(meet in the middle)

    一眼题...这个数据范围也太明显了吧... suma1==suma2 && sumb1==sumb2 && sumc1==sumc2 相当于suma1-sumb1==s ...

  8. [学习笔记]矩阵乘法及其优化dp

    1.定义: $c[i][j]=\sum a[i][k]\times b[k][j]$ 所以矩阵乘法有条件,(n*m)*(m*p)=n*p 即第一个矩阵的列数等于第二个矩阵的行数,否则没有意义. 2.结 ...

  9. 图像处理之中值滤波介绍及C实现

    1 中值滤波概述 中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号平滑处理技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值. 中值滤波的基本原理是把数字图像或数字序 ...

  10. Python高级语法总结

    1.Python面向对象 创建类 使用class语句来创建一个新类,class之后为类的名称并以冒号结尾,如下实例: class ClassName: '类的帮助信息' #类文档字符串 class_s ...