首页 > 编程语言 >UBOOT以太网驱动程序指南, uboot网卡驱动指南,u-boot网卡驱动编译教程

UBOOT以太网驱动程序指南, uboot网卡驱动指南,u-boot网卡驱动编译教程

时间:2024-08-09 16:49:06浏览次数:7  
标签:指南 struct int dev 网卡 驱动 eth ape 驱动程序

以太网驱动程序指南

Das U-Boot 中的网络堆栈设计允许在运行时轻松添加和控制多个网络设备。本指南适用于希望回顾网络驱动堆栈并实现自己以太网设备驱动程序的人员。在这里,我们将描述一个新的伪“APE”驱动程序。

大多数现有驱动程序已经(并且新的网络驱动程序必须)使用 U-Boot 核心驱动模型。有关这方面的通用信息可以在 doc/driver-model/design.rst 中找到,因此本文档将重点介绍网络特定的代码部分。一些驱动程序仍在使用旧的以太网接口,旧接口和新接口之间的差异以及移植提示将在文末处理。

驱动框架

遵循驱动模型的网络驱动程序必须使用 U-Boot 驱动程序结构中的 UCLASS_ETH .id 字段来声明自己:

c U_BOOT_DRIVER(eth_ape) = { .name = "eth_ape", .id = UCLASS_ETH, .of_match = eth_ape_ids, .of_to_plat = eth_ape_of_to_plat, .probe = eth_ape_probe, .ops = &eth_ape_ops, .priv_auto = sizeof(struct eth_ape_priv), .plat_auto = sizeof(struct eth_ape_pdata), .flags = DM_FLAG_ALLOC_PRIV_DMA, };

struct eth_ape_priv 包含运行时的每个实例数据,如缓冲区、指向当前描述符的指针、当前速度设置、指向 PHY 相关数据的指针(如 struct mii_dev)等。在 .priv_auto 中声明其大小将使驱动框架在适当的时间分配它。可以通过 dev_get_priv(dev) 调用来检索。

struct eth_ape_pdata 包含静态平台数据,如 MMIO 基地址、硬件变体、MAC 地址。struct eth_pdata 作为该结构的第一个成员有助于避免重复代码。如果您除了标准成员之外不需要更多平台数据,只需使用 sizeof(struct eth_pdata) 作为 plat_auto

PCI 设备添加了一个指向受支持的供应商/设备 ID 对的行:

c static struct pci_device_id supported[] = { { PCI_DEVICE(PCI_VENDOR_ID_APE, 0x4223) }, {} }; U_BOOT_PCI_DEVICE(eth_ape, supported);

也可以声明对整个 PCI 设备类别的支持:

c { PCI_DEVICE_CLASS(PCI_CLASS_SYSTEM_SDHCI << 8, 0xffff00) },

设备探测和实例化将由驱动模型框架处理,因此请遵循相关指南。probe() 函数将初始化硬件的特定平台部分,如时钟、复位、GPIO、MDIO 总线。同时,它还会处理任何特殊的 PHY 设置(电源轨、内部 PHY 的启用位等)。

驱动方法

实际工作将在驱动程序提供的驱动方法函数中完成,通过定义 struct eth_ops 的成员:

c struct eth_ops { int (*start)(struct udevice *dev); int (*send)(struct udevice *dev, void *packet, int length); int (*recv)(struct udevice *dev, int flags, uchar **packetp); int (*free_pkt)(struct udevice *dev, uchar *packet, int length); void (*stop)(struct udevice *dev); int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join); int (*write_hwaddr)(struct udevice *dev); int (*read_rom_hwaddr)(struct udevice *dev); };

最新版本的 struct 及更多信息可以在 include/net.h 中找到。

只有 startstopsendrecv 是必需的,其余的为可选的,通常由通用代码处理或在未提供时被忽略。

start 函数初始化硬件并使其准备好进行发送/接收操作。你通常会在这里做一些操作,如重置 MAC 和/或 PHY,并等待链路自动协商。你还应该利用这个机会用 enetaddr 成员(这是你自己 plat 结构的第一个成员)来编程设备的 MAC 地址。这使 U-Boot 的其余部分可以动态更改 MAC 地址并使新设置生效。

send 函数执行你想的事情——传输指定大小的包(以字节为单位)。包缓冲区可以(也将会!)被重用于后续的 send() 调用,因此在 send() 函数返回时必须不再使用。实现这一点的最简单方法是等待传输完成。或者,如果硬件支持,只等待缓冲区被消耗(由某个 DMA 引擎)也可能是一种选择。另一种消耗缓冲区的方式是将数据复制到要发送的包中,然后将复制的包排队(例如交给 DMA 引擎),然后立即返回。在任何情况下,你都应该使状态保持在可以多次连续调用 send 函数的状态。

recv 函数轮询新包的可用性。如果没有可用包,它必须返回 -EAGAIN。如果收到一个包,确保它对 CPU 可访问(如有必要,失效缓存),然后将其地址写入 packetp 指针,并返回长度。如果发生错误(接收错误、包过短或过长),如果需要包被正常清理,则返回 0,否则返回负错误代码(不需要清理或已经完成清理)。U-Boot 网络堆栈将处理该包。

如果定义了 free_pkt,U-Boot 会在处理完接收到的包后调用它,以便释放或回收包缓冲区。通常你会将其交还给硬件以获取另一个包。free_pkt() 会在 recv() 之后被调用,对于同一个包,因此你不必从包指针推断要释放的缓冲区,而可以依赖于这是 recv() 处理的最后一个包。通用代码已经在 .bssnet_rx_packets)中为你设置了包缓冲区,因此通常不需要分配自己的缓冲区。然而,这并不意味着你必须使用 net_rx_packets 数组;你可以自由使用任何你希望的缓冲区。

stop 函数应该关闭/禁用硬件并将其放回重置状态。它可以在任何时间(在相关 start() 函数调用之前)调用,因此请确保它能处理这种情况。

(可选)write_hwaddr 函数应将存储在 pdata->enetaddr 中的 MAC 地址编程到以太网控制器中。

所以此时的调用图可能如下:

scss (某些网络操作(ping / tftp / whatever...)) eth_init() ops->start() eth_send() ops->send() eth_rx() ops->recv() (处理包) 如果 (ops->free_pkt) ops->free_pkt() eth_halt() ops->stop()

CONFIG_PHYLIB / CONFIG_CMD_MII

如果你的设备支持在 MII 总线上使用任意值(几乎所有设备都支持),你应该添加对 mii 命令的支持。这样做相当简单,并且使得在运行时调试 MII 问题变得容易得多。

在驱动程序的 probe() 函数中,添加对 mdio_alloc()mdio_register() 的调用,如下所示:

c bus = mdio_alloc(); if (!bus) { ... return -ENOMEM; } bus->read = ape_mii_read; bus->write = ape_mii_write; mdio_register(bus);

然后定义 mii_readmii_write 函数(如果你还没有定义的话)。它们的语法很简单:

c int mii_read(struct mii_dev *bus, int addr, int devad, int reg); int mii_write(struct mii_dev *bus, int addr, int devad, int reg, u16 val);

read 函数应该从地址为 addr 的 PHY 读取寄存器 reg,并将结果返回给调用者。write 函数的实现应该逻辑上跟随 read

旧版网络驱动程序

!!! 警告 !!!

以下部分描述了旧的做法。任何新的以太网驱动程序都不应以这种方式实现。所有新的驱动程序都应按照上述 U-Boot 核心驱动模型编写。

实际的回调函数非常类似,区别在于:

start() 被称为 init()

stop() 被称为 halt()

recv() 函数必须循环直到接收到所有数据包,对于每个数据包,它必须调用 net_process_received_packet() 函数,将指针和长度传递给它。之后,它应该释放包,然后检查新数据。

要将旧驱动程序移植到新

标签:指南,struct,int,dev,网卡,驱动,eth,ape,驱动程序
From: https://www.cnblogs.com/aldary/p/18351047

相关文章

  • 致钛固态硬盘误删数据恢复指南(2024版)
    在当今这个数字化时代,数据已经成为我们生活和工作中不可或缺的一部分。无论是珍贵的家庭照片、重要的工作文件,还是学习资料,都存储在各类存储设备中,其中固态硬盘(SSD)因其高速读写能力而备受青睐。然而,误删数据的情况时有发生,尤其是在使用致钛等高性能固态硬盘时,一旦操作不慎,重要......
  • Docker基本命令及容器数据卷的配置,Docker网卡的简单理解
    基本组成概念镜像(images):好比一个模板,可通过该模板来创建多个容器服务。容器(container):利用容器技术可以独立运行一个和一个组应用,使用镜像来创建,类似于实例化镜像。仓库(repository):存放镜像的地方。http://hub-mirror.c.163.comhttps://registry.docker-cn.comhttps:/......
  • 【迅为电子】IMX6ULL开发板嵌入式linux开发指南第七章 Linux 常用命令第一部分
        物联网时代,各种传感器的采集和处理技术是需要我们掌握的,迅为IMX6ULL开发板标配了各种传感器设备,包括陀螺仪、重力加速度计和光传感器、红外接收、EEPROM存储,也可以选配温湿度传感器,其他如摄像头(含CMOS和USB两种)、VGA显示、GPS定位功能、RFID门禁、继电器输出、步进电......
  • 创新驱动,中国EL冷光片市场蓬勃发展
    一、行业简述(一)行业概念EL冷光片,全称为电激发光冷光片,是一种利用电场激发荧光物质发光的物理现象来实现发光的器件。EL冷光片通过施加交流电压,在电极之间产生强电场,从而激活发光层中的荧光材料,使其发出均匀、柔和的冷光源。由于其低功耗、颜色多样、寿命长等特点,EL冷光片在......
  • 三防平板定制化:驱动产业高效化发展的新动能
    在数字化转型的浪潮中,三防平板作为一种坚固耐用、功能强大的移动设备,正逐渐成为各行各业提升效率、优化管理的关键工具。通过硬件和软件的定制化服务,三防平板不仅能满足特定行业的需求,更能在复杂的工作环境中展现出卓越的性能,助力产业实现高效化发展。硬件定制化:打造专属设备......
  • KubeSphere 部署 Kafka 集群实战指南
    本文档将详细阐述如何利用Helm这一强大的工具,快速而高效地在K8s集群上安装并配置一个Kafka集群。实战服务器配置(架构1:1复刻小规模生产环境,配置略有不同)主机名IPCPU内存系统盘数据盘用途ksp-registry192.168.9.904840200Harbor镜像仓库ksp-co......
  • 真想转行做大模型?AI产品经理们,先看看这份指南
    如果你想转行做大模型,作为一名AI产品经理,你可以怎么做呢?或许,你可以先进行自我检测,看看自己是否真的适合转行做大模型。这篇文章里,作者便给想转行做大模型的AI产品经理们提出了一些建议,不妨来看看吧。作为一个产品经理,你可能已经熟悉了一些常见的AI技术和应用,比如机器学......
  • 连接云数据库RDS for MySQL的全方位指南
    在云端高效管理数据,掌握连接RDSforMySQL的技巧一、应用程序访问VPC内RDSforMySQL实例的正确姿势确保您的应用程序所在的ECS与RDSforMySQL实例位于同一VPC。若不在,请调整VPC的路由表和网络ACL,以便ECS能够顺利访问RDSforMySQL实例。二、外部服务器访问云数据库RDSfor......
  • 裁员失业后的自救指南
    昨天写了一篇关于关于降薪裁员及打工人如何应对的文章,最初是为了回答星球同学的问题,顺带给大家做一些关于裁员赔偿的基础科普。没成想后台很多同学留言,说了很多他们的被裁员经历。有裁员后很快找到工作的,也有好几个月找不到工作被迫“灵活就业”的。我筛选统计了一下,大部分留言......
  • Linux源码阅读笔记20-PCI设备驱动详解
    PCI基础PCI总线为高性能局部总线,主要解决外部设备之间以及外部设备与主机之间高速数据传输。在数字图形、图像等处理,以及告诉实时数据采集与处理等队数据传输速率要求高的应用中,采用PCI总线进行数据传输。PCI规范能够实现32位并行数据传输,工作频率为33MHz或66MHz,最大吞吐率......