一、ffu升级步骤
1. READ EXT_CSD cmd8
EXT_CSD[493] SUPPORTED_MODES
: Check FFU Supportability
EXT_CSD[169] FW_CONFIG
: check FFU Prohibited or not
EXT_CSD[261-254] FIRMWARE_VERSIOIN
: check current firmware version
2. Set ‘FFU Mode’ cmd6+0x031E0100
3. Write patch file at one write command.
cmd23+0x00000400
cmd25+0xC7810000
4. Disable FFU Mode, get back to Normal Mode
cmd6+0x031E0000
5. Reset Device (S/W Reset, H/W Reset, Power cycle)
6. READ EXT_CSD cmd8
EXT_CSD[26] FFU_STATUS
: checking the result of FFU process. 0 means success.
EXT_CSD[261-254] FIRMWARE_VERSIOIN
: After FFU, FIRMWARE_VERSION Field is updated to the number of new patch
二、ffu升级分析
在高通sdhci的驱动代码中,sdhci_adma_table_pre接口会判断发送数据的长度是否大于65536字节(64KB),大于则会导致kernel crash。
crash日志:
尝试把BUG_ON(len > 65536);注释,让代码继续跑下去,发送cmd25命令数据出现失败,cmd25数据传输失败io error ADMMA error
翻看sdhci高通文档,adma限制最大的descriptor table的数据长度为64kb,因此在代码中有BUG_ON(len > 65536);的限制。
既然ADMA有限制,列出以下修改的几种可能方案:
1、看看是否可以把固件缩小到64K
2、把固件数据拆分为多个包发送到底层
3、改用SDMA
4、底层kernel分包传输
5、看看ADMA是否是能扩展到512K
根据三星提供的手册,固件数据不能分成多个包进行写入。且把固件包压缩为64k也不实际,所以排除1、2方案
目前高通配置的是adma,改为sdma改动比较大
翻看高通代码相关的修改,mmc: sdhci: Fix ADMA for PAGE_SIZE >= 64KiB
有将数据包分成32kb的大小依次传输,合入该patch后,固件可以升级成功。
三、问题总结
根据三星提供的手册,固件数据不能分成多个包进行写入,mmc程序把固件包512KB ioctl发送到kernel,Kernel crash,高通驱动代码最大只能发65536字节,所以在此进行了拦截。
底层将其分成32kb字节传输之后,emmc ffu可以升级成功
-
mmc-utils,
source code :CodeLinaro / la / platform / external / mmc-utils · GitLab