尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

用Glasgow读取SPI Flash:从接线到固件备份的完整实战指南

用Glasgow读取SPI Flash:从接线到固件备份的完整实战指南 玩硬件逆向和固件分析的人迟早要做一件事Dump Flash Memory Devices——把一颗Flash芯片里的内容完整读出来。备份原厂固件、提取配置参数、抢救老设备里的标定数据这种场景我几乎每周都能遇到。过去我一般抓一个CH341A编程器或者干脆用树莓派飞线但这两条路各有各的别扭。直到Glasgow Interface Explorer进了我的工具盒这件事才算真正变得顺手。这篇文章就是一次完整记录怎么用Glasgow从认识芯片开始一路走到把整片Flash安全地读出来、存成文件、并且验证数据没错。适合手里有硬件、想自己做固件备份或者做逆向分析的开发者参考。Glasgow这名字听起来像个城市名实际是个开源硬件调试工具的全称。它不是普通的USB转串口小板而是一块以FPGA为核心的多协议接口探索器。所谓接口探索器你可以理解成一个能随时变身各种总线协议工具的瑞士军刀今天当SPI主机读Flash明天当I2C主控读EEPROM后天当JTAG链上的调试器甚至还能充当简单的逻辑分析仪。这篇文章只讲它在Flash读取方面的用法但这个背景决定了很多设计上的取舍理解之后你就不会在使用时犯一些方向性错误。1. 为什么用Glasgow来读Flash1.1 先从接口探索器这件事说起Glasgow的核心是一颗Lattice的iCE40UP5K FPGA。FPGA的特点是内部电路可以按需求重构而且一旦配置好信号时序就完全由硬件逻辑产生不依赖操作系统的调度。对比一下你就能理解差异用树莓派的GPIO模拟SPI实际上是靠CPU一条条指令去翻转电平一旦系统有中断或者后台进程抢时间片波形上就会出现毛刺和抖动。而Glasgow的SPI时序是在FPGA内部用硬件状态机生成的时钟边沿的位置精确到纳秒级连续读几兆字节也不会出现读到一半电平抖了一下这种事。这意味着在需要稳定读取大容量Flash的场景下Glasgow比通用单片机方案靠谱得多。从项目形态上看Glasgow的设计文件完全开源固件和上位机软件也都是开源项目社区一直在维护。它的上位机是一个Python命令行工具名字就叫glasgow通过USB 3.0和板子通信。你不需要知道FPGA内部怎么跑只需要在PC上敲命令让它加载对应的applet可以理解成一台仪器加载测量程序再指定引脚和参数剩下的协议波形由硬件负责。这种架构带来的最大好处是不管跑什么协议操作方式都是同一套逻辑学一次就能通吃。1.2 和其他方案对比为什么它值得选我在Glasgow之前用过CH341A编程器、树莓派GPIO、还有Bus Pirate。这几个方案我都踩过坑放到一张表里你们感受一下方案读SPI Flash优势主要痛点CH341A编程器便宜软件开箱即用上位机大多在Windows芯片支持列表有限没法灵活处理非典型场景树莓派GPIO flashrom便宜、可脚本化电平抖动速度慢逻辑分析能力弱还要自己处理电平转换Bus Pirate多协议命令行操作芯片老协议支持更新慢高速场景表现一般GlasgowFPGA硬件时序跨平台开源CLI协议丰富价格比CH341A高FPGA工具链对新手有学习成本对比下来Glasgow最大的价值不是能读出Flash——那三个方案都能做到而是它在同一个工具里把多协议和稳定时序结合起来。你不需要因为换了I2C的EEPROM就再买一个编程器也不需要为了一个冷门协议临时翻树莓派GPIO的驱动代码。接上USB加载对应的applet问题就解决了一大半。另外Glasgow对操作系统的态度也友好。它不是一个绑定在Windows驱动里的工具而是标准的USB设备加Python客户端Linux、macOS、Windows都能跑。这一点对于长期做嵌入式开发或者固件分析的人来说非常关键你的工作流是脚本化的可以不离开终端完成整个读取任务后续分析也能直接接入现有的Python生态。2. 动手前先搞清楚的硬件细节2.1 认识你要读的Flash芯片在接线之前第一步永远是确认芯片型号而不是急着用夹子去夹。常见用于存储固件的Flash芯片主要是两类一类是SPI NOR Flash比如Winbond W25Q系列、Macronix MX25系列、GigaDevice GD25系列另一类是I2C EEPROM比如Atmel/Microchip的24C系列。前者容量大从几百KB到64MB甚至更大常用于存固件后者容量小几KB到几百KB常用于存配置参数。这篇文章以SPI NOR为主因为它的读取流程更典型也更容易踩到坑。芯片上的丝印通常标了厂商缩写和型号数字比如W25Q128JVSI、MX25L25645G通过丝印在搜索引擎或者厂商官网一查就能拿到datasheet。拿到datasheet以后先看三件事工作电压、封装和引脚功能、支持的最大SPI时钟频率。这三项直接决定你的接线和后续参数设置。另外做这种操作前务必确认你对目标设备有合法处置权自己手里的开发板、已经停产的自家设备都没问题别去动不属于自己的东西。以最常见的SOIC-8封装W25Q系列为例8个引脚的典型定义是1脚CS#片选低电平有效2脚DO也就是MISO3脚WP#写保护可以暂时不管4脚GND5脚DIMOSI6脚CLK7脚HOLD#一般建议拉高或者悬空8脚VCC。这个排列在很多SPI NOR芯片上是通用的但你别直接套用所有芯片特别是封装不一样的SOIC-16、WSON-8、TSSOP-8引脚位置差异很大必须查datasheet确认。2.2 Glasgow引脚分配与接线方法Glasgow板子上的对外接口一般分两组每组连接器都提供一组用户IO引脚以及电源和地。用SPI读Flash时至少需要4根信号线CS、CLK、MOSI、MISO再加VCC和GND一共6根线。具体引脚编号在不同版本板子上可能有细微差别动手前先看自己手头板子的丝印和官方文档确认IO0到IO3的位置。我建议刚上手时先在桌面上用一个SOIC-8的测试座来练习把芯片夹在座子上然后再用杜邦母对母线接到Glasgow。如果你要读的芯片已经焊在目标板子上可以考虑用测试夹比如SOP8的夹子夹住芯片但要注意目标板如果还有别的电路可能存在总线干扰这个问题我放到后面排查部分细说。如果是长期要分析多块板子焊接飞线其实是最稳的方案虽然麻烦一点但接触电阻和稳定性都远胜夹子。接线时记住一个原则Glasgow的MOSI接芯片的MOSI也就是DIGlasgow的MISO接芯片的MISO也就是DOCS接CSCLK接CLK共地芯片VCC接Glasgow的电压输出。顺序接反是最常见的低级错误但也是最容易踩的尤其是MOSI和MISO反接——因为你读ID的时候它可能还能靠某些协议特性蒙混过关一旦读大段数据就全是乱的。2.3 供电和电平匹配的坑SPI NOR Flash的供电电压通常有3.3V和1.8V两类少数老芯片是5V。Glasgow的输出电压是可配置的一般支持1.8V、2.5V和3.3V档位具体看板子版本和文档。接芯片之前先把芯片的VCC电压搞清楚然后设置Glasgow的输出和芯片一致否则轻则读不到数据重则烧芯片。我自己的习惯是在任何带电操作之前先用万用表打一遍VCC和GND之间有没有短路再确认Glasgow输出的电压档位这套检查30秒但能挡住八成事故。另一个容易忽略的问题是当芯片在目标板上时它的CS、MISO、MOSI可能已经被板上其他器件连接了。如果板子上还有主控或者其他外设同时占用了这个SPI总线你直接夹上去读很可能会因为总线冲突读出一堆乱码。稳妥的做法是如果只是想备份原厂固件尽量找到板子上的供电方式让主控处于复位状态或者断电状态只给Flash供电并通过Glasgow操作如果做不到就把芯片吹下来用测试座读虽然麻烦但结果最干净。3. 实战完整Dump一块SPI NOR Flash3.1 搭好工具链先装上位机。最简单的办法是用pip安装pip install glasgow安装完成后把Glasgow通过USB 3.0接到电脑。Linux下需要先放行udev规则否则普通用户访问不了USB设备。项目文档里有现成的规则文件拷到/etc/udev/rules.d/下然后执行sudo udevadm control --reload-rules sudo udevadm trigger搞定后重新插拔USB运行glasgow --help能看到帮助信息就说明工具链没问题。这一套在Windows和macOS上也类似只是驱动方式略有不同核心思路是先确认操作系统能看到USB设备再确认Python客户端的权限。如果你喜欢折腾也可以从源码编译那会用到Yosys和NextPNR这套FPGA工具链但日常使用完全没必要release工具直接装就行。3.2 识别芯片先别急着开读读取之前花10秒钟让Glasgow自己探测一下芯片。运行spi-flash这个applet并指定引脚和电压。不同版本的参数写法略有差别建议先执行glasgow run spi-flash --help确认参数名。大致形式是这样的glasgow run spi-flash --voltage 3.3 --pin-cs 0 --pin-clk 1 --pin-mosi 2 --pin-miso 3 probeprobe动作会让Glasgow向芯片发送SPI读ID指令0x9F然后解析返回的JEDEC ID。比如你手里是一颗W25Q128JV它的JEDEC ID是EF 40 18Glasgow会直接告诉你检测到Winbond W25Q128容量16MB。看到这个结果就说明接线、供电、协议参数全部正确可以放心往下一步走。如果probe识别不到芯片先别怀疑工具按我实践中的经验九成是接线或者供电问题。把第2章的检查项过一遍VCC有没有电、GND通不通、CS是不是真被拉低了、MISO/MOSI有没有接反。还有个小技巧换一根杜邦线试试别问我为什么这个坑我踩了不止一次接触不良是所有硬件调试里最隐蔽的敌人。3.3 执行读取并验证文件识别到芯片之后读取就是一条命令的事glasgow run spi-flash --voltage 3.3 --pin-cs 0 --pin-clk 1 --pin-mosi 2 --pin-miso 3 read --output flash.bin读取过程中工具会显示进度16MB的芯片在默认SPI时钟下几十秒到一两分钟能读完具体速度取决于芯片支持的SPI时钟上限和线材质量。读取完成以后立刻观察文件大小是不是和芯片容量一致。如果芯片是16MBflash.bin应该正好是16MB多一个字节都说明过程有问题。拿到文件不等于工作完成。我对所有读出来的Flash文件都会做两件验证第一再读一遍比对两次文件的sha256值是否一致sha256sum flash.bin如果两次哈希不一致说明读取过程中有数据错误大概率是线路干扰或者时钟太高需要降速重读。第二用一个十六进制查看器打开文件看看内容分布比如xxd flash.bin | head -n 20。通常一个合理的固件文件开头会有中断向量表或者引导头内容不是纯00或者纯FF。如果你看到一个文件的前16KB全是0xFF那基本可以断定读取是失败的别把它当经验数据保存。如果有需要还可以更进一步用binwalk跑一遍看看里面有没有文件系统、压缩包或者未加密的配置块。这一步对固件分析来说非常关键它能帮你快速判断读出来的文件是否包含了完整的固件映像也方便后续解包分析。3.4 调整SPI时钟与读取速度Glasgow默认的SPI时钟可能不是芯片的极限速度。如果你的线材比较短、焊接可靠可以尝试提高SPI时钟来加速读取。在我的使用中读取大容量NOR Flash时提速效果还是很明显的但代价是容错率下降。如果出现数据校验失败就把SPI时钟降一档再读。这个平衡点没有统一配方简单说就是速度快慢以读两次哈希一致为验收标准不达标就降速。有一个经验值得反复强调不要认为读出来没有报错就等于数据正确。SPI协议层的CRC校验在普通SPI NOR Flash上不是默认开启的工具端如果不做二次比对你根本无法知道某个时钟边沿上有没有采到错误的电平。所以我的流程固定是识别→读取→哈希比对→再读一次→哈希比对这一步即使麻烦也从不省。4. 常见问题与排查技巧4.1 设备不识别或者probe失败先从软件层查起。执行glasgow --help确认驱动和udev规则正常。如果系统能看到USB设备但glasgow连不上多半是udev规则没生效重启一下udev或者重新插拔。如果glasgow run能跑但probe失败问题就在硬件连接上。我的排查顺序是先用万用表量VCC对GND电压确认电源正常再量CS到GND在空闲状态是不是高电平因为CS低电平有效如果它被某些板子的上下拉电阻拉死了芯片永远处于选中或者非选中状态最后检查SPI四根线的通断特别是杜邦线母座松动导致的接触不良。另外一个容易被忽略的点是Glasgow的引脚索引未必和物理位置一一对应不同版本的固件、不同的applet参数引脚编号规则可能不同。我建议你在probe之前先用一个简单方法确认你的引脚映射接一颗已知完好的芯片用文档里的示例参数跑通再换目标芯片。这样至少把工具链的未知量排除干净。4.2 读回来的文件全是一堆0xFF或0x00全0xFF这个现象很典型。如果你读到的文件所有字节都是0xFF说明芯片根本没有被选中或者MISO上没有数据返回。常见原因有三个CS没有真正拉低——芯片不响应任何SPI指令MISO线接错或者断线——主机发出的指令芯片正常处理了但返回数据的通道是断的芯片供电没到位——尤其容易发生在用夹子夹住芯片但VCC没接触好的情况。全0xFF还有一个反向原因你读取的起始地址和容量设置有问题。如果工具按Page或者按Sector批量读某个环节的地址计算出了偏差也会产生大量空数据。不过Glasgow的spi-flash applet在probe成功后会按照芯片容量自动配置读取范围所以只要probe是对的很少出这种问题。全0x00则更可能是电压问题。如果VCC太低或者GND存在电位差芯片上电状态不对数据线可能一直被拉低。遇到0x00先查供电再查MOSI和MISO是否对GND短路。4.3 数据读到一半跳变或者校验不稳定这种情况我最常遇到原因通常跟线材和接触质量有关而不是芯片本身坏了。杜邦线太长、母座氧化、夹子夹不住都会在高频下造成信号完整性问题。你的数据可能在几十KB以内都正确一旦跑大文件个别位就飘了。解决办法很简单换短一点的杜邦线或者直接用飞线焊接给芯片加一个0.1uF的退耦电容放在VCC和GND之间如果读取环境特别恶劣这个电容能明显改善稳定性最后就是降低SPI时钟别跟它硬刚速度。还有一种情况是目标板上其他器件干扰。我在读一张路由器的板载Flash时无论怎么降速都报校验错误后来发现板子的主控在复位失败后持续通过SPI总线访问Flash两个主机在抢总线。处理办法是把主控彻底断电或者根本不让它上电只给Flash单独供电。如果你不想拆芯片这是最实际的做法。4.4 遇到I2C EEPROM、NAND Flash等其他介质Glasgow不只读SPI NOR。I2C EEPROM对应的是i2c-eeprom这个applet流程几乎一样只是接线变为SDA、SCL两根线加VCC和GND读写逻辑和地址空间不同。NAND Flash也可以用Glasgow辅助操作但要复杂很多因为NAND没有标准的JEDEC ID查询指令容量和坏块信息都在芯片内部管理工具支持也相对有限。如果你要做NAND我建议先查一遍对应applet的文档确认你的NAND主控和芯片组合在支持列表里再动手。SD卡也可以归到存储介质这一类。Glasgow有sd卡相关applet但SD卡的规范和SPI NOR差异很大初始化流程复杂读卡速度也受限于卡本身。如果只是备份一张普通SD卡用读卡器比Glasgow更实际。工具不在多够用就行这也是我反复提醒自己的。最近一次读一颗老款交换机上的Flash翻到之前记录的照片发现上一次我把MISO和MOSI接反了都浑然不觉就是因为没有做两次读取校验。现在这套流程固定下来以后出错的概率低了很多。所以我一直建议刚接触这个工具的人别急着追求速度先把识别→读取→哈希比对→确认内容结构这套流程走顺后面遇到再复杂的存储芯片思路都是通的。工具永远只是工具真正让你放心的还是自己亲手跑完的验证流程。
返回列表