简介:Marvell 6390/6190系列芯片SDK是一套面向嵌入式开发者的完整软件开发包,包含驱动、API、示例代码及文档,可帮助工程师快速实现网络控制器、存储控制器等外设的驱动与应用开发。压缩包共365个文件,以180个C源文件和135个头文件为主,辅以makefile、工程配置文件、库文件和DLL,整体大小仅1.02MB,结构清晰,便于按模块检索。内容预览显示其中有PortCtrl、TCAM等模块源码,覆盖了端口控制与三态内容寻址存储器等关键功能,对于理解Marvell交换芯片的编程模型很有参考价值。已有1347人下载学习,适合从事网络设备、嵌入式系统及物联网方案开发的学习者和工程师。通过这套SDK,开发者可以借鉴其层次清晰的代码组织和API封装思路,减少底层适配工作,集中精力于业务逻辑,同时熟悉芯片初始化、调试和性能优化的典型流程。 这篇东西本来是给团队内部新人做的入门文档,后来想想干脆整理成博文。起因是一个做网络交换的定制项目,主控选了Marvell的芯片,硬件同事把板子抓得很漂亮,结果到软件这边,SDK一解压我就知道事情没那么简单。如果你刚接触Marvell芯片SDK,手头项目又要赶进度,希望这篇能帮你少走几趟弯路。思路可以复用,不管是SoC、PHY还是存储主控方向,Marvell的SDK套路和踩坑点之间其实有大量相似之处。
1. 拿到Marvell SDK之后,先别急着编译
很多人一拿到SDK压缩包,第一反应就是解压、make、烧固件,然后被一堆不知道哪来的报错劝退。实际上Marvell的SDK结构非常“工程化”,但也非常“老派”——它把芯片厂商过往几十年的项目管理习惯都留在里面了。先花半天把包里的东西摸清楚,绝对比闷头编译划算。
1.1 SDK压缩包里的结构比你想象得更“整”
Marvell各条产品线的SDK形式不完全一样,但大体上会包含这么几个部分:
- 芯片原厂提供的U-Boot源码和Linux内核补丁;
- 专门的外设驱动,比如PHY、switch、DDR、PCIe相关的;
- 编译工具脚本、编译配置模板;
- 官方文档,包括硬件手册、SDK使用指南、Release Notes;
- 大量example代码,通常放在
examples/或applications/下。
我拿到手的这个包大概1.5GB,解压后看目录结构就清楚了。建议第一步不是编译,而是打开Release Notes。里面会写清楚这个SDK版本支持哪颗具体芯片、对应的Linux内核版本、U-Boot版本、修了哪些bug,以及已知问题。碰到离谱报错时,这些信息能帮你判断是SDK本身的问题,还是你配置环境的问题。第二件事是看文档目录下的README,很多编译前置条件和依赖都写在那里,只是大多数人懒得看。
1.2 文档和示例代码是真正的新手救星
Marvell官方文档的命名风格比较直白,比如MV-SDK-UM-xxxx.pdf的User Manual,信息密度很高,但排版相当复古。里面会有API说明、寄存器定义、启动流程、数据路径说明。新人最容易犯的错误是拿通用Linux驱动知识硬套,结果发现Marvell的接口封装了一层又一层。
真正的捷径是看example代码。比如你想搞清楚一个网络包从网口进来到CPU的路径,examples/里通常有一个最简单的收包函数,一步步对着读,比啃文档管用得多。这些example虽然功能简单,但所有初始化顺序都是齐的,照着改不会漏步骤。
我自己习惯拿到SDK后,先在源码目录里执行一次git log或者看版本号文件,确认分支和芯片型号完全匹配。之前遇到过一次尴尬:SDK里默认配置是A型号CPU,我用的是同系列B型号,编译出来烧进去连串口都没输出,排查了很久才发现是CPU型号配置不对。这类低级错误,看Release Notes和配置文件就能在半天内规避。
2. 交叉编译环境与固件构建的典型坑
Marvell芯片的固件构建,基本都逃不开交叉编译。这一步本身不复杂,但环境的“水土不服”最能消磨耐心。我在这部分卡过的时间,加起来足够看完一部剧。
2.1 工具链选择:按芯片架构对号入座
Marvell既有基于Armv7的SoC,也有Armv8、MIPS、x86(某些网卡和存储产品)架构,不同SDK要求你用不同的交叉编译工具链,千万不要拿一个通用arm-linux-gnueabihf-gcc通吃所有项目。
以Armada系列为例,老一些的芯片常用32位工具链(arm-linux-gnueabihf-),新一些的则要求aarch64-linux-gnu-。SDK的build脚本里通常会写死默认工具链路径,但不同批次SDK对GCC版本的要求是有差异的。太新的GCC会报“unknown option”或者头文件找不到,太老的GCC又可能编不过新版内核。
建议直接在SDK文档里找到推荐的工具链。我踩过最深的坑是在Ubuntu 22.04上用自带GCC 11编某款老芯片的内核,结果make死在math.h的某个宏上,后来换回SDK文档推荐的具体版本才顺利通过。
2.2 编译u-Boot和内核时的三个常见报错
这些都是Marvell SDK开发群里高频出现的问题,处理方式也相对固定:
| 报错现象 | 最常见原因 | 解决方法 |
|---|---|---|
scripts/kconfig/Makefile: No such file or directory | 内核源码未解压完整,或子模块未拉取 | 检查SDK目录完整性,重新解压 |
fatal error: curses.h: No such file or directory | 缺少menuconfig依赖库 | 安装libncurses-dev |
error: Cannot use CONFIG_CC_STACKPROTECTOR_STRONG | 工具链与内核配置不匹配 | 内核对GCC版本有要求,换匹配的工具链 |
这些报错看着低级,但很考验对构建系统的理解。比如CONFIG_CC_STACKPROTECTOR_STRONG那个错误,本质是编译器无法通过内核的栈保护测试,不少人在网上搜半天,最后发现就是工具链版本不对。
2.3 DDR training和硬件拓扑配置为什么必须改
U-Boot编译出来烧进去如果起不来,十有八九是DDR配置不对。Marvell的DDR控制器初始化非常依赖板级硬件拓扑信息,内存颗粒的位宽、密度、片选数量、总线频率,全部写在board目录下的某个ddr_topology相关的头文件或配置表格里。
SDK默认的配置一定是针对官方开发板的,你拿到自制板子上烧人家默认固件,内存参数对不上,连启动早期都过不去。最典型的表现是:上电后串口打印到一行DDR training相关日志就卡死,或者直接什么都没有。
我第一次调DDR的时候,误以为Marvell的“自动训练”能覆盖所有参数差异。实际上它只能在一定范围内自动校准时序,但总线位宽、Address mapping这些拓扑级别的东西必须手动匹配硬件原理图。正确做法是翻开硬件工程师给的DDR part number,去内存厂商官网查datasheet,把CS、DQS、列地址位宽这些参数填进配置。做完这一步,很多稀奇古怪的启动失败会不治自愈。
3. SoC启动与固件烧录:先按住复位键那套流程
Marvell SoC的启动过程,从BootROM开始。芯片上电后,BootROM先初始化最小系统,从SD卡、SPI NOR、NAND或者UART等启动介质引导U-Boot。你需要搞清楚自己的板子支持哪些启动方式,以及boot switch拨到了什么位置。
3.1 BootROM到U-Boot:芯片上电后发生了什么
这步理解透了,后面调试串口输出才有思路:
- BootROM代码在芯片内部,不可修改,负责从选定介质加载U-Boot SPL;
- SPL做最基础的DDR初始化,然后把完整U-Boot加载到DDR;
- U-Boot继续初始化外设,读环境变量,引导内核。
光看串口输出就能判断卡在哪一步。什么输出都没有,问题可能在电源、时钟、启动介质选择;如果输出停在DDR training,问题基本就是上一节说的拓扑配置;如果U-Boot起来但内核起不来,那就要查设备树和外设驱动了。这个排查路径是我反复用了无数次的。
3.2 UART烧录手法:复位键配合调试软件的完整操作
没有烧录器的时候,Marvell芯片一般支持通过UART把固件烧进NOR/NAND/eMMC。网上常说的“先按住芯片复位键(NRST),在调试软件里点连接,连接成功后松开复位键,然后擦除”,其实就是UART烧录的标准操作。
实操流程是这样的:
- 把板子串口连接到电脑,装好驱动;
- 打开Marvell官方烧录工具(不同产品线叫法不同,有些叫
DDR training tools,有些包含在SDK tools里); - 第一步先按住板上的复位键不松手;
- 在软件里点“连接”;
- 软件开始等待握手信号后,立刻松开复位键;
- 此时BootROM会因检测到UART启动模式而进入下载流程,软件就可以擦除或写入Flash了。
这个手法的原理是:BootROM在上电复位后会短暂检测启动介质,如果在复位释放瞬间UART口收到指定握手字符,它就进入串口下载模式。按住复位键是为了人为控制复位释放的时机,让PC端和板端同步。如果先松开复位键再去连,BootROM可能已经去读别的介质了,自然无法建立连接。
3.3 烧录失败后的恢复思路
UART烧录最常见的问题是“连接超时”。优先级排列如下:
- 先确认串口的TXD和RXD有没有接反。这个低级错误,我见过不止一个人反复中招。
- 再看波特率,Marvell BootROM下载模式通常固定波特率,不同芯片不一样,常见有115200和38400,工具里选错就直接握手失败。
- 然后检查复位键是否真的把芯片复位,有些板子的复位键只复位物理层PHY,不复位主控,那按住也没用。
- 最后确认启动介质选择引脚,如果拨到SPI启动,那么UART强制模式未必生效。
实在不行,把Flash芯片拆下来用编程器烧录,是最保底的方案。虽然操作麻烦,但至少不会卡在软硬件握手问题上。
4. PHY/Switch SDK的实际调用:从寄存器到功能
Marvell在网络芯片领域相当强势,PHY和Ethernet Switch产品线很全。硬件工程师喜欢Marvell的PHY,因为它稳定;软件工程师有时候会骂它,因为寄存器映射文档实在太多页了。
4.1 用MDIO把PHY拉通
驱动一个PHY,绕不开MDIO总线。MDIO有一个管理接口,通过它读写PHY寄存器,去配置速率、双工模式、Auto-Negotiation,以及读取链路状态。Marvell的PHY驱动在Linux内核里已经很成熟,你大概率不需要从零写,但改设备树时要把phy地址、phy mode写对。
实际调试中,我更习惯先在u-Boot下用mdio命令直接读写PHY寄存器。比如先读寄存器0(基本控制)、寄存器1(基本状态),确认PHY的链路是否建立。如果reg 1的bit2为1,说明链路已经up,否则就是物理链路问题。在u-Boot下确认LAN端能link,再进内核排查驱动,效率会高很多。
4.2 Switch SDK的常用API和CLI
Marvell交换芯片SDK和普通PHY驱动不是一个量级。它有一套自己的API框架,包含VLAN、FDB、端口镜像、ACL等大量功能。以mv88E6xxx系列为例,Linux内核里有dsa驱动框架,把Switch抽象成一个个标准网口。但如果你要用到更底层的功能,Marvell会提供专门的Switch SDK(比如switch API库),这时API命名通常是mv_sw_xxx这种风格,配置VLAN就是先创建一个VLAN对象,再把端口加进成员列表,最后应用到底层。
SDK包里通常还带一个CLI工具,可以通过串口或telnet进入,敲switch_cli类似的命令就能读端口状态、配置VLAN。相比纯API编码,CLI更适合验证硬件和网络拓扑。我曾经在排查一个二层不通的问题时,用CLI把每个端口的PVID和VLAN成员表打出来,五分钟就定位到了是某颗芯片的默认配置没设对。
4.3 为什么PHY灯亮但ping不通
做网络设备调试,最玄幻的问题是——PHY灯亮了,网线也插着,但ping不通。
灯亮只代表物理层协商成功,不代表链路层和网络层正常。常见原因有:
- 网口所属的Switch端口VLAN没有配正确,报文被丢弃;
- MAC侧没有使能收发,或者MAC和PHY之间的RGMII信号有问题;
- 报文格式问题,比如Tagged和Untagged没配对。
我的排查习惯是:先在板子上用ifconfig确认网口是UP状态,再看kernel log有没有link up事件,然后用ethtool eth0看speed/duplex是否匹配,最后在Switch CLI里查端口收发包计数。如果发现MAC收到了包但发不出去,那十有八九是PHY的寄存器里TX使能位被关掉了,或者MAC的发送FIFO被复位搞坏了。这个问题在Marvell平台见过好几回,恢复方式是复位整个switch再重新初始化一次。
5. 存储主控SDK与开卡工具的那点事
Marvell在存储控制器领域也很出名,热词里提到的88SS9189就是经典SATA SSD主控之一。这类产品面向量产场景,软件开发主要围绕开卡工具和固件来做。
5.1 88SS9189和开卡工具的使用场景
SSD主控芯片出厂后是“空片”状态,需要加载固件,划分好闪存通道、坏块管理、SMART参数等等,这个过程在行业内叫“开卡”。Marvell存储主控的SDK里,除了固件源码,还会配套开卡工具,通常以Windows下的图形软件形式出现,作用是给SSD量产或者修复。
日常研发中,最常见的两个场景:
- 硬件调试阶段,需要反复升级固件调整参数;
- 板卡故障导致固件损坏,SSD不认盘,用开卡工具救回来。
开卡工具一般要通过USB转SATA或者直接SATA接口连接,工具识别到主控后,可以擦除原有内容、重新写入固件和相关配置参数。
5.2 ROM模式操作与参数配置
Marvell SSD主控有一种强制ROM模式,让主控跳过固件加载,直接等待开卡工具上传新固件。不同主控进入ROM模式的方式不同,常见有:
- 通过厂家调试命令触发;
- 短接板上的ROM跳线;
- 在主控空片或固件损坏状态下,部分主控会自动进入ROM模式。
连接成功后,工具界面里需要填很多东西:闪存颗粒型号、通道数、CE数、页面大小、坏块处理策略、盘容量、版本号等等。
我这边的建议是,参数配置务必对照SSD板卡上的贴片信息,不要靠猜。开卡工具里如果选错闪存颗粒型号,轻则开卡速度下降,重则直接写坏固件区域,让SSD变得更难救。特别是坏块处理策略,量产盘一般会自动扫描并映射坏块,但有些工具默认不启用,必须手动勾选。
5.3 开卡前必须确认的三件事
开卡工具威力大,破坏性也大,操作前我建议至少确认三件事:
- 这个盘是不是测试盘:别拿存有客户数据的盘来试SDK流程,开卡操作会把整个用户可见区域和数据区一起重建,数据基本无法恢复。我在团队里是专门留了几片“折腾盘”的。
- 供电是否稳定:开卡过程中断电,主控可能进入半砖状态,虽然多数情况下还能重新进入ROM模式再刷,但那种心跳加速的感觉没人想经历。
- 工具版本和固件版本要匹配:不同固件版本对闪存管理算法的要求不一样,乱配的话,开卡报错信息会非常误导人——比如明明显示“工具未连接”,实际却是固件不兼容导致主控没法进入下载状态。
我也被“开卡工具检测不到主控”折腾过一次,查了一圈最后发现是SATA转USB硬盘盒的桥接芯片太老,对SSD主控的特定命令支持不好,换了一条直连SATA线后就正常了。遇到检测不到设备,先怀疑硬件连接,而不是反复点连接按钮。
6. 最后分享两个调试习惯
Marvell SDK相关的坑,很多不是原理层面的,而是顺序和习惯问题。我在几个项目里积累的小习惯,现在看来收益很大。
一是每次改动硬件配置前,先把备用的cap文件保存好。比如DDR拓扑参数、PHY地址映射、Flash分区表,这些配置改坏的时候,能一键回到可用状态,就能节省大量重来时间。
二是建立自己的“最小验证清单”。拿到板子后,先用官方SDK默认配置烧一遍,确认板子能启动到U-Boot,再去改自己项目的功能。如果这一步失败,就不要急着碰其他模块,先把基础启动链路搞定。这个清单虽然只有十几行,但每次都能快速区分“硬件问题”和“软件改动引入的问题”。
Marvell芯片SDK的水很深,但门道清楚了就不慌。希望这篇能让你少走一些弯路,如果你也是从串口没日志开始一步步磨过来的,相信看完会有不少共鸣。
本文还有配套的精品资源,点击获取