找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
广告投放联系QQ68610888
查看: 13328|回复: 61

让 MT7621 等不支持 SPI-NAND 的路由器直接从 SPI-NAND 上启动

  [复制链接]
原帖地址:https://blog.hackpascal.net/2020 ... -spi-nand-directly/
转载请注明原帖链接和作者!



在现在看来,现今比较老的一批路由器芯片,以 Atheros/QCA/MediaTek 等的 MIPS 平台的芯片为代表,基本都只支持从 SPI-NOR 启动。
如果要使用 SPI-NAND,就必须使用双 Flash 方案,即从 SPI-NOR 上启动,再从 SPI-NAND 上加载固件。
对于现有的方法,从单 Flash 改为双 Flash 就很不容易。如果是新设计的方案,双 Flash 会增加额外的物料成本和开发成本,不划算。

说到底,这还是因为 SPI-NOR 跟 SPI-NAND 使用的读指令的时序不同:

SPI-NOR 的 Read data (03h) 指令时序:

总结为 1个字节的 Opcode + 3字节的地址 + 输出数据

SPI-NAND 的 Read from cache x1 (03h) 指令时序:

总结为 1个字节的 Opcode + 2字节的地址 + 1字节的无用时钟 + 输出数据

可以看到这两者差异还是很明显的。而 CPU 读取数据的时序是固定不变的,即 SPI-NOR 的时序。因此这类 CPU 是不能从 SPI-NAND 上启动的。



但是,Micron 在他们的 SPI-NAND 中,提供了一个功能,可以将自身的 Read from cache x1 (03h) 和 Fast read from cache x1 (0Bh) 的时序转换为 SPI-NOR 的时序。
并且绝大部分 SPI-NAND 在上电之后都会将其第一个 page 的数据加载至 cache 里面,Micron 的当然也不例外。
这样,CPU 就能够直接访问到 SPI-NAND 第一个 page 的数据了。虽然一个 page 普遍都是 2KB 大小,少部分是 4KB。


根据描述,这个功能需要一系列复杂的操作才能开启,而且这个功能是不会因为断电就失效的。
但是,Micron 只提到了怎么开启这个功能,而没有提到怎么关闭这个功能。事实上我测试和发现,这个功能一旦开启就不能关闭了。



那么,能否在有限的 2KB 大小内,写一份代码让 MT7621 直接从 SPI-NAND 上启动呢?
显然我做到了。我的设计如下:

整个 Bootloader 分为3个部分:
  • 第一阶段,此时没有内存可用。需要将第二阶段的代码从 SPI-NAND 读取出来并执行。
  • 第二阶段,初始化 CPU 内存等,并加载第三阶段
  • 第三阶段,即常规的 Bootlaoder,例如 Breed 或者 U-Boot

虽然 MT7621 有 24KB 的 SRAM 可用,但是考虑到第二阶段大小必定大于 24KB,因此第二阶段只能放在 cache 上执行。
MT7621 有 256KB 的 L2 cache,4-way。MIPS 规定最多 3 way 可以被锁定,也就是最多 192KB 的 L2 cache 可以被用于加载第二阶段,完全足够了。

因此,第一阶段需要完成如下操作:
  • 初始化 MIPS CPS,以便于能够进行 cache 初始化操作
  • 初始化 cache,并锁定一部分用于加载第二阶段
  • 初始化 spi-nand 驱动,并加载第二阶段到 cache
  • 执行第二阶段

第二阶段主要就是加载并执行 MTK SDK U-Boot 中提供的初始化内存的 mt7621_stage_sram.bin,然后完成其余必要的初始化操作。
最后执行 spi-nand 驱动,加载第三阶段到内存,并执行

所以开发难点在于第一阶段,如何将这么多功能塞进 2KB 以内。
首先当然是精简代码,只保留必要的部分。
然后就是利用 CPU 和编译器的特性:
MIPS CPU 支持 mips16 压缩指令,因此这个选项必须要开启
再一个是 gcc 编译器的链接时优化 (Link-time optimization, LTO) 功能。通常的优化都只能在一个源代码中进行优化。
这个 LTO 功能可以跨越源代码文件边界,将全部源代码看成一个整体进行进一步优化,减小体积。
只不过要注意的是 LTO 一直存在 BUG,因此只给第一阶段使用,不能给后续阶段使用。

最终我成功将第一阶段的大小控制在了 1.88KB 左右。这里面还有一个本可以去掉的串口输出功能。



然后就是 Bootloader / Kernel 适配了。

要能支持 SPI-NAND,U-Boot 最好选用 Upstream的,因为它已经支持 spi-nand framework 了。
但是 Upstream U-Boot 并不支持 MT7621 因此作罢。
而给 MTK SDK U-Boot 增加 SPI-NAND 支持工程量更大,因此不考虑。
最后就只有 Breed 可以胜任了。

而 Kernel 正式支持 SPI-NAND 需要版本 4.18 及之后了,当然 4.14 版本也可也轻松 backport。
Kernel 的 spi-nand 驱动需要进行修改,识别 SPI-NAND 是否开启了 NOR Read 功能,如果开启了,就要修改 spi-mem op template,调整其 read_cache 的时序。
另一点是,开启 NOR Read 之后, 03h 和 0Bh 这两个指令的时钟频率不能高于 20MHz,否则会得到错误的数据。因此 dts 里面要限制其 spi master的速率。

另外,开启了 NOR Read 的 SPI-NAND 存在一个跟 SPI-NOR 32MB 类似的软重启问题。
跟 SPI-NOR 直接读取存储的数据不同,SPI-NAND 的 03h/0Bh 指令是读取的内部 cache 的数据,而真实存储的数据需要预先在 SPI-NAND 内部读取到 cache 后,才能通过 03h/0Bh 读出。
而要将数据写入 SPI-NAND,也是先将数据加载到 cache,SPI-NAND 内部才会将数据实际写入。
这样会带来的一个显而易见的问题就是,cache 内的数据会随着对 SPI-NAND 的操作而不断变化,而软重启后,cache 的数据就是未知的了,且99.99%的概率不是第一个 page 的数据。
这会导致软重启无法开机。因此解决办法自然是在每次完整的读写操作之后,都执行一个加载第一个 page 的数据到 cache 的命令,以保证正常操作性,软重启能正常执行。



实际测试结果

第一二阶段 + Breed 输出:


Kernel 内 spi-nand 相关的输出:




我将第一二阶段的源代码放在 github 上:
https://github.com/hackpascal/mt7621-boot-spi-nand

对 kernel 的修改:
https://github.com/hackpascal/openwrt-dev/commits/mt7621-boot-spi-nand

测试用的 bootloader 和固件:
https://pan.baidu.com/s/17aWbKr7QzKWw8zw7fog_nw
提取码:8iqj

loader-no-payload.bin 不含第三阶段,可以自行拼接。
loader-breed.bin 的第三阶段是 Breed。

关于如何开启 SPI-NAND 的 NOR Read 功能,没有统一的方法,使用编程器,或者通过 ft2232 这类支持 SPI 的芯片,下发 Micron 手册上描述的指令,来开启

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×

评分

参与人数 8恩山币 +12 收起 理由
忒*** + 1 一看就是觉得高端、大气、上档次!.
╩华夏*** + 2 简直完美!
hw*** + 1 一看就是觉得高端、大气、上档次!
WeD*** + 2 一看就是觉得高端、大气、上档次!
ITd*** + 2 支持一波大佬
那个*** + 1 兄弟,你肥皂又掉了…
我妻*** + 2 强大的恩山!(以下重复1万次)
dl*** + 1 恩山全体路由党向你学习!

查看全部评分

我的恩山、我的无线 The best wifi forum is right here.
前排广告位.
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

虽然没看懂,感觉很牛逼
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

受益良多
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

膜拜大佬,顶上↑↑↑↑↑
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

利害
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

大佬又出现了!一直用你的Breed,谢过~
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

摩拜摩拜
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

没有沙发了
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

Mark!

另:最近遇到一个问题,newifi D1 /D2 SPI-NOR 32MB ,breed+openwrt官方19版

在使用了 AdGuard Home(非luci)官方Github后,软重启就失效了,LED灯也一直慢闪状态。

删掉 AGH 也是恢复不了。还在研究是什么问题造成的。

breed已经修复了SPI-NOR 32MB 软重启问题了。在没有启动AGH的时候也是没有异常,看样子,AGH会改动系统的配置??

我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

看来,

不久就会让很多双盘位的机型有得玩了..

H大就是...

我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

神人神操作
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

膜拜大神,不明觉厉~
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

牛A,虽说现在MT7621已经算不上热门,但市场存量实在是庞大,各种机型/配置够多
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

虽然没看懂,但感觉很牛逼
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

有疑问请添加管理员QQ86788181|手机版|小黑屋|Archiver|恩山无线论坛(常州市恩山计算机开发有限公司版权所有) ( 苏ICP备05084872号 )

GMT+8, 2024-4-27 21:48

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

| 江苏省互联网有害信息举报中心 举报信箱:js12377 | @jischina.com.cn 举报电话:025-88802724 本站不良内容举报信箱:68610888@qq.com 举报电话:0519-86695797

快速回复 返回顶部 返回列表