數位天堂

Nokia:科技始終來自於人性; 拜耳:如果文明不能使我們更相愛,那科技便失去意義!
歡迎您的加入,讓我們一起討論科技與環保的結合應用...

您尚未登入。

站內搜尋

#1 2011-12-14 15:02:04

hippo
天使
註冊日期: 2008-10-07
文章數: 1562
目前積分 :   20 

[Tomato USB(泰迪熊)] 交叉編譯器的使用

在網路上有諸多程式, 原始碼是C語言. 要將程式用於機器上, 得事先編譯為機器能懂的二進位執行檔. 以微軟的術語來說, 就是.exe, .com的執行檔. 若未編譯, 只能看的到, 吃不著.

為何使用交叉編譯器? 在原生機器(Router)上面編譯, 相容性最好, 但機器的CPU太慢, RAM太少, 導致編譯費時, 一覺醒來, 可能還沒編譯好. 所以使用x86, amd64的PC, 藉PC的高速運算, 將C原始碼交叉編譯為目標機器(Router)的執行檔.

泰迪熊放在捷克的原始碼, tomato-ND-USBmod是K24, tomato-RT, tomato-RT-N是K26. 因泰迪熊原始碼支援USB, 依泰迪熊原始碼所衍生的土司超人等諸多版本, 也是使用相同的交叉編譯器. 而泰迪熊的交叉編譯器來源, 可能是Lly. 若PC是64位元, 可使用Lly釋出的x86_64 Toolchain.

編譯原始碼前, 先準備編譯平台GNU/Linux.(廢話!) 不論是安裝在虛擬機器, 或是另一顆硬碟都行. 選用自己喜歡的Linux發行版本, 安裝必要套件, 營造編譯平台. 安裝的必要套件可參考Lly wiki, 或twtomato相關的.rar檔案. 套件名稱依Linux發行版本的不同, 或許會有些微差異. 所以得自己熟悉套件管理程式, 搜尋, 安裝套件.

安裝git套件, 參考這篇, 透過git下載原始碼. 先決定要使用哪個衍生版本, 再下載正確的分支. 下載完畢後, 您可嘗試編譯韌體, 順道測試編譯平台相關套件是否安裝妥當. 編譯韌體不是本文重點, 略過不提.

git下載的原始碼, 內含交叉編譯器. 以K26來說:

$ ll ~/Tomato/tomato-RT/tools/brcm/K26/hndtools-mipsel-uclibc-4.2.4/ total 44 drwxr-xr-x 2 abel abel 4096 Jun 3 2011 bin/ drwxr-xr-x 17 abel abel 4096 Jun 3 2011 include/ drwxr-xr-x 2 abel abel 4096 Jun 3 2011 info/ -rw-r--r-- 1 abel abel 93 Jun 3 2011 info.mk drwxr-xr-x 5 abel abel 4096 Jun 3 2011 lib/ drwxr-xr-x 3 abel abel 4096 Jun 3 2011 libexec/ drwxr-xr-x 4 abel abel 4096 Jun 3 2011 man/ lrwxrwxrwx 1 abel abel 19 Jun 3 2011 mipsel-linux -> mipsel-linux-uclibc/ drwxr-xr-x 4 abel abel 4096 Jun 3 2011 mipsel-linux-uclibc/ drwxr-xr-x 4 abel abel 4096 Jun 3 2011 share/ drwxr-xr-x 2 abel abel 4096 Jun 3 2011 stamp/ drwxr-xr-x 2 abel abel 4096 Jun 3 2011 target-utils/


bin目錄內有mipsel開頭的gcc等執行檔與連結, 這些就是在PC上交叉編譯要用到的執行檔. gcc版本是4.2.4, uClibc呢? 查lib目錄, uClibc版本是0.9.30.1. 所以, 若使用Lly釋出的Cross Toolchain, 要選擇對應正確的版本.

好, 先來交叉編譯試試, 建立自信心. 取最簡單的CPU與RAM效能測試的原始碼openwrt_cpu_bench_v06.c來開刀. 使用文字編輯器, 貼上原始碼, 注意斷行, 存檔為openwrt_cpu_bench_v06.c
編譯:

$ ~/Tomato/tomato-RT/tools/brcm/K26/hndtools-mipsel-uclibc-4.2.4/bin/mipsel-linux-gcc -o cpubench openwrt_cpu_bench_v06.c


檢查:

$ file cpubench cpubench: ELF 32-bit LSB executable, MIPS, MIPS32 version 1 (SYSV), dynamically linked (uses shared libs), not stripped


將編譯後的cpubench上傳(FTP, SCP等)到Router, 變更檔案屬性為可執行, 測試:

# chmod +x cpubench # ./cpubench


如果看到效能測試結果, 恭喜, 搞定第一步了.

參考Tomato Utilities, 交叉編譯是經由script來執行. 以微軟的術語來說, 就是批次檔.bat. 那也來參照測試.
$ nano build.sh

#!/bin/sh export PATH=$HOME/Tomato/tomato-RT/tools/brcm/K26/hndtools-mipsel-uclibc-4.2.4/bin:$PATH mipsel-linux-gcc -o cpubench openwrt_cpu_bench_v06.c


$ chmod u+x build.sh $ ./build.sh


經由指定環境變數$PATH, 可省事不少. script入門, 請參考網中人, 鳥哥. 理解script後, 您可能高呼: 阿母, 我出運了! 還沒啦, 繼續吃鐵牛運功散吧.

交叉編譯前, 先決定編譯後的程式放在目標平台(Router)哪個目錄.

# echo $PATH /bin:/usr/bin:/sbin:/usr/sbin:/home/root:/mmc/sbin:/mmc/bin:/mmc/usr/sbin:/mmc/usr/bin:/opt/sbin:/opt/bin:/opt/usr/sbin:/opt/usr/bin:


/bin, /usr, /sbin, 唯讀, 想都別想. /home/root, 記憶體, 關機後, 程式就不見蛋了. 所以只能放在USB HD等, 掛載到對應的目錄. JFFS? 行, 但得想想有多少空間可存放程式.

在PC的Linux創建目標平台的目錄架構. 假設您編譯後的程式, 預計放在/opt/usr/bin內, 也就是將/opt/usr當成根目錄.

$ mkdir -p ~/Work/opt/usr $ su # cd /opt # ln -s /home/使用者/Work/opt/usr usr


為何這樣搞?
1. 因為編譯後的程式, 一般都放在/usr/local等相關目錄, 參考後面的configure說明.
2. 目標平台的/usr/local是唯讀, 無法寫入, 也不是預計放置程式的目錄.
3. 藉由指定--prefix=/opt/usr, make install會將編譯後的執行檔, 函式庫, 說明等, 放在/opt/usr.
4. 若用root編譯, 權限太高, 迷糊手賤時, 會誤刪系統檔案, 搞垮整個PC的Linux.
或許您會說, 那我建個/opt/usr目錄, 允許使用者有權限寫入就好了. 行, 當然可以, 電腦是您的, 可摔可踢, 任君自由.
同理, 若預計放在目標平台的/jffs, 也是依自己的方式操作.

接著就是找原始碼. 先選套小型的工具程式, 就Wget好了. Wget原始碼在何處? 在Google找到原始碼網站, 下載, 沒問題. 但另有一個簡便的方法, 就是查看Linux套件資訊. 以Optware來說,

# ipkg-opt info wget Package: wget Version: 1.12-2 Conflicts: wget-ssl Status: unknown ok not-installed Section: net Architecture: mipsel maintainer: NSLU2 Linux MD5Sum: 3ad0feecfc0198045068159e238b6d83 Size: 186025 Filename: wget_1.12-2_mipsel.ipk Source: http://ftp.gnu.org/pub/gnu/wget/wget-1.12.tar.gz Description: A network utility to retrieve files from the Web


Source就告訴您來源了. GNU在國網中心或學術網路都有鏡射, SourceForge國網中心也有鏡射, 就不必捨近求遠了. 當然, 也可由PC的Linux, 透過套件管理程式查詢相關資訊.

如何下載? 說這些太囉唆了, 照樣略過不提. 解壓縮後的原始碼, 必先參閱README, INSTALL等說明, 裡面會告訴你許多密技. 甚麼? 英文看不懂! 別哭爹喊娘了, 您還沒到編譯錯誤的頭痛階段呢! 這點小事, 聰明的您應該知道翻譯工具吧. 如果這也不知道, 我勸您趁早收手, 天冷, 較早睡, 較有眠.

$ ./configure -h `configure' configures wget 1.13.4 to adapt to many kinds of systems. Usage: ./configure [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print `checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for `--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or `..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [/usr/local] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, `make install' will install all the files in `/usr/local/bin', `/usr/local/lib' etc. You can specify an installation prefix other than `/usr/local' using `--prefix', for instance `--prefix=$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/wget] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-opie disable support for opie or s/key FTP login --disable-digest disable support for HTTP digest authorization --disable-ntlm disable support for NTLM authorization --disable-debug disable support for debugging output --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --disable-largefile omit support for large files --enable-threads={posix|solaris|pth|win32} specify multithreading API --disable-threads build without multithread safety --disable-nls do not use Native Language Support --disable-rpath do not hardcode runtime library paths --disable-ipv6 disable IPv6 support --disable-iri disable IDN/IRIs support Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --without-ssl disable SSL autodetection --with-ssl={gnutls,openssl} specify the SSL backend. GNU TLS is the default. --with-gnu-ld assume the C compiler uses GNU ld default=no --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib --without-libiconv-prefix don't search for libiconv in includedir and libdir --with-libintl-prefix[=DIR] search for libintl in DIR/include and DIR/lib --without-libintl-prefix don't search for libintl in includedir and libdir --with-libpth-prefix[=DIR] search for libpth in DIR/include and DIR/lib --without-libpth-prefix don't search for libpth in includedir and libdir --with-libssl-prefix[=DIR] search for libssl in DIR/include and DIR/lib --without-libssl-prefix don't search for libssl in includedir and libdir --with-libgnutls-prefix[=DIR] search for libgnutls in DIR/include and DIR/lib --without-libgnutls-prefix don't search for libgnutls in includedir and libdir --with-libidn=DIR Support IDN/IRIs (needs GNU Libidn) Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l<library> CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to .


因為不打算使用SSL, 所以改良後的script如下:
$ nano build.sh

#!/bin/sh Name=wget Ver=1.13.4 export PATH=$HOME/Tomato/tomato-RT/tools/brcm/K26/hndtools-mipsel-uclibc-4.2.4/bin:$PATH export CC=mipsel-linux-gcc export CPP=mipsel-linux-cpp cd $Name-$Ver make distclean ./configure \ --host=mipsel-linux \ --target=mipsel-linux \ --prefix=/opt/usr \ --without-ssl [ $? -eq 0 ] && make && make install


如果您問到CFLAGS, CPPFLAGS等, 有何作用? 這難以三言兩語道盡, 請自行man或info gcc, ld等.
如果您注意之前編譯的cpubench, MIPS32 version 1 (SYSV), 這表示是MIPS R1/R2的機種可吃. 若要編譯為MIPS R2專用的呢?
$ man gcc

MIPS Options -EL -EB -march=arch -mtune=arch -mips1 -mips2 -mips3 -mips4 -mips32 -mips32r2 -mips64 -mips64r2 -mips16 -mno-mips16 -mflip-mips16 ...


有答案了吧! 當然, 進階還可微調相關參數, 可參考泰迪熊或Rodney的Tomato Utilities是怎麼玩的.
如果您的PC是多核心CPU, make可加入-j參數. 詳情請man make.

開工, 編譯.

$ ./build.sh


啪拉啪拉跑一堆訊息出來. 若有興趣, 可將螢幕輸出導向檔案存檔, 慢慢研究. 參考網中人, 鳥哥的教學.
如果編譯沒出錯,  /opt/usr/bin/wget就是執行檔了. 除執行檔外, 還有相關的說明文件. 使用tree指令查看整個編譯結果.

$ tree /opt/usr/ /opt/usr/ ├── bin │ └── wget ├── etc │ └── wgetrc └── share ├── info │ └── wget.info └── man ├── man1 │ └── wget.1 └── whatis 6 directories, 5 files


至此, 我建議您將整個/opt/usr目錄打包壓縮, 省去日後再編譯的時間.

$ mkdir ~/Done $ cd /opt/usr $ tar -czf ~/Done/wget-1.13.4.tar.gz *


同樣的, 上傳到目標平台, 測試結果.

日後多編譯幾套程式後, 您就會知道如何調整script. 而因程式是放在USB HD等儲存空間, 也就暫時先不管縮小程式體積與最佳化等. 有興趣者, 可研讀gcc相關文件. 更進一步就是改良原始碼, 回饋社群了...
收工!




離線

 

#2 2015-11-18 13:31:53

rv2231
新生
註冊日期: 2015-02-15
文章數: 11
目前積分 :   

Re: [Tomato USB(泰迪熊)] 交叉編譯器的使用

關於 搭建編譯環境  這邊有一篇 供入門者參考   "從零開始學習OpenWrt:刷機 + 使用 + 編譯教程"http://upsangel.com/openwrt/openwrt-beginner-guide/



離線

 

相關討論主題

主題 回覆 點閱 最後發表
200 139968 昨天 07:38:40 作者 won701201
Tomato Shibby v140 韌體更新 作者 Service  [ 1 2 3 … 10 ]
99 48386 2018-09-16 12:55:47 作者 dnangelj
409 311250 2018-09-16 11:26:10 作者 dnangelj
置頂
置頂: [Tomato Shibby] 正體中文化韌體下載 作者 Aven  [ 1 2 3 … 145 ]
1447 800784 2018-09-16 03:23:14 作者 dnangelj
置頂
置頂: [Tomato 衍生版本] 新功能預覽測試 作者 hippo  [ 1 2 3 … 8 ]
76 102047 2018-08-27 11:33:12 作者 koko0417

友情連結

論壇頁尾

Powered by PunBB
© Copyright 2018 Rickard Andersson
RSS Feed