LZMA ERROR 1 - must RESET board to recover錯誤分析

因爲項目的需要,編譯了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的頭部信息:

image

顯然,後面的數據大小是有問題的!對比一下OP的一個firmware,就能更加清楚:

image

初步分析,問題可能出現在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.7
image: 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)

 

打完收工,一樁懸案終於水落石出… …

發佈了59 篇原創文章 · 獲贊 12 · 訪問量 43萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章