因爲項目的需要,編譯了MTK官方的4.1版SDK,最終生成了manfeel_uImage文件,刷入開發板之後重啓,出現了這個LZMA ERROR 1的錯誤。是我運氣太好,還是太背?上次也碰到過這個問題,改動了一下load address(由原來的0x80000000改成了0x80100000),就過了。然而,這次的問題貌似沒那麼簡單。
只好深入uboot的lib_generic/lzmaDecode.c中一探究竟。解壓縮lzma數據的函數原型是:
int lzmaBuffToBuffDecompress(char *dest,int *destlen,char *src,int srclen);
看了代碼之後,不得不吐槽一下寫這個代碼的人,爲神馬任何錯誤,作者都返回1?是作者太自(Zi)信(Da),還是認爲人們不需要了解錯誤的細節?好,抱怨歸抱怨,代碼是必須要分析的,加上一些診斷輸出代碼後,發現了有用的信息:
stream version is not supported, outSize = FFFFFFFF
LZMA ERROR 1 - must RESET board to recover
對照該部分代碼分析:
memcpy(properties,src,sizeof(properties));
src += sizeof(properties);
outSize = 0;
for (ii = 0; ii < 4; ii++)
{
unsigned char b;
memcpy(&b,src, sizeof(b));
src += sizeof(b);
outSize += (unsigned int)(b) << (ii * 8);
}
if (outSize == 0xFFFFFFFF)
{
//sprintf(rs + strlen(rs), "\nstream version is not supported");
printf("\nstream version is not supported, outSize = %X\n", outSize);
return 1;
}
for (ii = 0; ii < 4; ii++)
{
unsigned char b;
memcpy(&b,src, sizeof(b));
src += sizeof(b);
if (b != 0)
{
//sprintf(rs + strlen(rs), "\n too long file");
printf("\n too long file");
return 1;
}
}
大概分析了一下lzma的頭部信息:
顯然,後面的數據大小是有問題的!對比一下OP的一個firmware,就能更加清楚:
初步分析,問題可能出現在lzma壓縮上,是否是lzma版本導致的問題?
進入source/vendors/Ralink/MT7620,查看Makefile
發現這個該死的Makefile調用的居然是系統默認的lzma文件,Ubuntu14.04的lzma版本是:
xz (XZ Utils) 5.1.0alpha
liblzma 5.1.0alpha果斷修改,將4.32.7版本的lzma拷貝到source目錄,修改Makefile如下:
#manfeel, do NOT use the system default lzma(5.1.0alpha), just use the 4.32.7image: mkimage$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S $(ROOTDIR)/$(LINUXDIR)/vmlinux $(KERNELZ)cd $(IMAGEDIR) ; rm -f $(KERNELZ).*; ../$(COMP) -v -9 -f -S .$(COMP) $(KERNELZ)
打完收工,一樁懸案終於水落石出… …