Linux手機DIY.庫檔案專題.交叉編譯的浮點問題

來源:互聯網
上載者:User

 Linux手機DIY.庫檔案專題.交叉編譯的浮點問題

草木瓜  於 2006-11-9

一、序

  交叉編譯過程的浮點問題可畏老大難,各個gcc的版本相容性不一,所對應的patch效果差異又很大。這對構造不同於E680的E600編譯環境造成了很大麻煩,這裡我對嘗試的過程做下描述,以供參考,畢竟中文資料少得可憐。

二、重要提示

    為了方便更好的理解本文,提供下面鏈結。
    全系列的文章地址,手機應用開發專欄:http://blog.csdn.net/liwei_cmg
    相關的重要成果的:http://play.younet.com/view.php?tid=24045

三、浮點問題的由來

  MOTO E680 系列,夏新E600和飛利浦968 等等手機,皆使用Inter Xscale的
處理器,所採用的指令集也是armv5tel。

  E680G 版本資訊
  Linux (none) 2.4.20_mvlcee30-mainstone #1 Jan 1,2003 armv5tel unknown
  E600 版本資訊
  Linux c8k 2.4.19-rmk7-pxa2 #1 Thu Mar 23 17:56:36 CST 2006 armv5tel unknown
  968 版本資訊
  Linux c8k 2.4.19-rmk7-pxa2 #1 Fri Dec 9 16:42:58 CST 2005 armv5tel unknown
  
  Inter Xscale這款新型高效能、低功耗的微構架相容ARMv5TE ISA指令集,
不過不支援浮點指令集。這是為了節省處理器晶片體積和降低運行功耗,XScale
體繫結構沒有實現昂貴的浮點運算組件和除法組件。這些是嵌入式應用中不常用
的運算。當需要這類運算時,要通過軟體方法實現。
  浮點運算要大大複雜於整數運算,沒有浮點運算單元會有什麼問題?
  
  我們來看一個例子:
  E680/E680i/E680g CPU都是ARM系列的Intel xScale PAX270。MP3解碼有兩種
方式,一種是基於浮點運算(如MPG123),另一種則是基於整數的,即libmad (MPEG
audio decoder library)。浮點的解碼,單精確度浮點小數可以精確到小數點後45位,
不過要求CPU有FPU單元。由於E680系列本身的限制,只能使用軟浮點,libmad是用
的fixed-integer,通過整數類比小數計算的,精度只能保留到小數點後第9位(大於
0的最小值0.00000000372529)。解碼精度和速度自然會有差異。因此這類手機音質
自然是不能與硬體解碼相比。也很少有EQ均衡器,即便通過軟體實現了,效果也不
是太好。
  
  此外流行的影像處理、3D運算、視頻處理、音頻處理等諸多多媒體應用都會類
似的涉及浮點運算。沒有FPU單元就需要軟體支援,顯然犧牲了效率和品質。
  浮點運算能力是關係CPU多媒體、3D圖形處理的一個重要指標。
  我們構建編譯開發環境,就需要加入軟浮點支援,否則涉及浮點運算就會出錯。

  
四、庫檔案格式

  先看E680系列的庫檔案格式。如libjpeg.so檔案,用objdump -p顯示相關內容:    
  private flags = 602: [APCS-32] [VFP float format] [software FP] [has entry point]

  顯然是software FP,不過使用的是VFP(Vector Float Point)向量浮點格式。
  
  再看E600和968的庫檔案格式:
  private flags = 202: [APCS-32] [FPA float format] [software FP] [has entry point]
  
  與E680相比,不同點在於使用的是FPA(Floating Point Arithmetic)浮點格式,
又一說為(Fixed Point Arithmetic)定點浮點運算。由於這方面知識空白,具體並
沒有仔細考證。
  
  當然除此兩種之外,還有一種格式
  private flags = 2 : [APCS-32] [FPA float format] [has entry point]
  這個自然是硬浮點格式了,不過如果在編譯過程中加上arm-nolibfloat patch
再在gcc參數加上-msoft-float,估計也是能產生軟浮點代碼,不過沒有親試。

  理論上講,不管是哪種格式,在應用程式運行連結時都是可以的,不存在相容
性的問題,但是要做編譯,庫檔案是必須完全一致的。

  以我手中的交叉編譯工具為例,當初是構建於E680G的VFP格式,我使用夏新
E600內建的QTE庫(FPA soft FP),編譯一個簡單的QTE程式,出現如下錯誤:

  /home/gcc/toolchain/soft-arm-linux/gcc-3.3.2-glibc-2.3.2/bin/../lib/
gcc-lib/arm-linux/3.3.2/../../../../arm-linux/bin/ld: ERROR: /home/gcc/
toolchain/qt/lib/libqte-mt.so uses FPA instructions, whereas helloqt does not
  /home/gcc/toolchain/soft-arm-linux/gcc-3.3.2-glibc-2.3.2/bin/../lib/
gcc-lib/arm-linux/3.3.2/../../../../arm-linux/bin/ld: failed to merge
target specific data of file /home/gcc/toolchain/qt/lib/libqte-mt.so
collect2: ld returned 1 exit status

  這個編譯環境是用cross-tool-0.28編譯而成的,而且打了gcc-3.3.2的soft-
float patch,不過按patch說明,是應該可以產生FPA soft FP格式的編譯環境,而
結果卻是VFP soft FP,這個適用於E680系列,然不適用夏新E600和飛利浦968。

  後來我在交叉編譯環境中把GCC_EXTRA_CONFIG的--with-float=soft選項去除
且把soft-float patch也同時去掉,獲得的是FPA hard FP的編譯環境。用這個環境
再編譯夏新E600內建的QTE庫(FPA soft FP),會出現類似如下提示:

    ld uses hardware FP, whereas libqte-mt.so uses software ...
   
    我試圖在gcc參數中加上-msoft-float,錯誤如下:
    arm-linux/bin/ld: cannot find -lfloat collect2: ld returned 1 exit status
   
    這個需要編譯編譯環境時加下nolibfloat的patch。
   
    如何產生FPA soft FP的格式困擾了好幾天,我查看了soft-float patch本身也
搜尋了大量資料,覺得可能還是patch本身的問題。我重新下載了gcc.3.4.0,使用
3.4.0 soft patch ,另外把bigendian,nolibfloat這一些有衝突的patch去掉,
果然產生了FPA soft FP格式的庫檔案。

  再用E600內建的QTE庫,編譯只是有一個警示選項:
  /home/gcc/toolchain/gcc-3.4.0-glibc-2.2.5/arm-linux/lib/gcc/arm-linux/3.4
.0/../../../../arm-linux/bin/ld: warning: libstdc++.so.5, needed by /home/gcc
/toolchain/qt-2.3.8/lib/libqte-mt.so, not found (try using -rpath or -rpath-link)

  夏新E600和飛利浦968使用的GCC版本都是3.2.1,3.4.0編譯後是libstdc++.so.6,
可以查看下面的lib內容,使用的版本是不同的。

  libstdc++.so.6
  
  Version definitions:
  1 0x01 0x025f4d66 libstdc++.so.6
  2 0x00 0x08922974 GLIBCXX_3.4
  3 0x00 0x056bafd3 CXXABI_1.3
  
  Version References:
    required from libgcc_s.so.1:
      0x0b792653 0x00 10 GCC_3.3
      0x0d696910 0x00 08 GLIBC_2.0
      0x0b792650 0x00 07 GCC_3.0
    required from libm.so.6:
      0x0d696910 0x00 05 GLIBC_2.0
    required from libc.so.6:
      0x09691f73 0x00 11 GLIBC_2.1.3
      0x0d696911 0x00 09 GLIBC_2.1
      0x0d696912 0x00 06 GLIBC_2.2
      0x0d696910 0x00 04 GLIBC_2.0

  libstdc++.so.5
  
  Version definitions:
  1 0x01 0x025f4d65 libstdc++.so.5
  2 0x00 0x081a2972 GLIBCPP_3.2
  3 0x00 0x0a297d01 GLIBCPP_3.2.1
   GLIBCPP_3.2
  4 0x00 0x056bafd2 CXXABI_1.2
  
  Version References:
    required from libm.so.6:
      0x0d696910 0x00 07 GLIBC_2.0
    required from libgcc_s.so.1:
      0x0b792650 0x00 06 GCC_3.0
    required from libc.so.6:
      0x0d696912 0x00 10 GLIBC_2.2
      0x09691f73 0x00 09 GLIBC_2.1.3
      0x0d696911 0x00 08 GLIBC_2.1
      0x0d696910 0x00 05 GLIBC_2.0
     
五、總結

  E600和968編譯環境問題看似是解決了,其實不然,這僅僅說明了可以生
成相容E600,968的庫檔案,能否運行則是另外一回事,下文將著重說明運行時
的相容性問題。
  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.