0. 前言
剛好最近有人來信詢問,就順便整理先前的一些文件一下,雖然 SimpleScalar 相對於現階段 ARM 的發展而言還停留在 ARMv4 的指令集,但若是在學術用途方面的話,還算是個相當有用的工具。但在研究初期最容易遇到的問題就是 toolchain 的問題,官方附贈的過舊,要自行建置則網路上資訊過於零散,建立出來也不見得能用...
而在這篇文章中會透過 buildroot 來建立一串基礎的 ARM toolchain ,來簡化整個建置的過程,若一般用途而言這樣的方式就夠了
另外此篇文章假設你已經有一個已經建立好的 SimpleScalar ARM 可以用了
1. 使用 buildroot 建置 ARM toolchain
buildroot 的官方網站是 http://buildroot.uclibc.org/download.html以下操作以 2012.08 的版本為例子,其它版本操作上大同小異,但部份路徑可能會有不同,第一次建議使用相同版本操作較為保險
目前作過測試是到 gcc 4.6 都可以在 SimpleScalar ARM 上運作沒有問題
gcc 4.7 因為不支援 ARM oabi 的部份所以會有點問題 (需要對 SimpleScalar 作一些修改)
i. 抓取 buildroot
wget http://buildroot.uclibc.org/downloads/buildroot-2012.08.tar.bz2
ii. 解壓縮 buildroot
tar -jxf buildroot-2012.08.tar.bz2
iii. 組態 buildroot
打入 make menuconfig 進入選單,會有 console 版本的選單出現make menuconfig
# 接著會進入選單 Target Architecture 按 enter 選 ARM (little endian) Target Architecture Variant 保留 generic_arm ,simplescalar 只支援 arm v4 Target ABI 選 oabi <--這是大重點,eabi 會不能動 Toolchain 點進去可以選 gcc 跟 binutils 版本 uClibc C library Version 選 uClibc 0.9.31.x ,太新會沒辦法用(需要用到 bx 指令, armv4 不支援) 需要 g++ 的話在 Enable C++ support 那邊按空白打 * 需要使用 hard floating point 則 Use software floating point by default 的 * 按空白拿掉其它看無就不用動
選擇最下面 Save an Alternate Configuration File
你會看到有一串
/home/kito/xxxxxxx/buildroot-2012.08/.config 之類的路徑
不要改
直接按 enter
然後 exit (左右可以移動下面的按鈕)
接著 make
然後轉身去泡杯咖啡,需要一點時間下載跟建置
build 完後在 buildroot 資料夾底下的
./output/host/usr/
這個資料夾
裡面就有 arm toolchain 了
iii. 測試 buildroot
先弄一個 Hello Worldecho "int main() {printf(\"hello world\");}" > hello.c編譯 Hello World ,-static 一定要加, simplescalar 只支援 static link
./output/host/usr/bin/arm-linux-gcc hello.c -o hello -static使用 SimpleScalar ARM 測試,前面的 path 記得自行替換成 simplescalar 的路徑
/<path-to-simplescalar>/sim-uop hello看到下面那一沱就代表你成功了!
sim-uop: SimpleScalar/ARM Tool Set version 3.0 of November, 2000. Copyright (c) 1994-2000 by Todd M. Austin. All Rights Reserved. This version of SimpleScalar is licensed for academic non-commercial use only. sim: command line: /home/kito/simulators/simplesim-arm-v2/sim-uop hello sim: simulation started @ Mon Oct 22 20:25:18 2012, options follow: sim-safe: This simulator implements a functional simulator. This functional simulator is the simplest, most user-friendly simulator in the simplescalar tool set. Unlike sim-fast, this functional simulator checks for all instruction errors, and the implementation is crafted for clarity rather than speed. # -config # load configuration from a file # -dumpconfig # dump configuration to a file # -h false # print help message # -v false # verbose operation # -i false # start in Dlite debugger -seed 1 # random number generator seed (0 for timer seed) # -q false # initialize and terminate immediately # -chkpt <null> # restore EIO trace execution from <fname> # -redir:sim <null> # redirect simulator output to file (non-interactive only) # -redir:prog <null> # redirect simulated program output to file -nice 0 # simulator scheduling priority -max:inst 0 # maximum number of inst's to execute -trigger:inst 0 # trigger instruction sim: ** starting functional simulation ** warning: unsupported ioctl call: ioctl(21505, ...) warning: unsupported ioctl call: ioctl(21505, ...) hello world sim: ** simulation statistics ** sim_num_insn 5276 # total number of instructions executed sim_num_uops 7095 # total number of UOPs executed sim_avg_flowlen 1.3448 # uops per instruction sim_num_refs 1259 # total number of loads and stores executed sim_elapsed_time 1 # total simulation time in seconds sim_inst_rate 5276.0000 # simulation speed (in insts/sec) ld_text_base 0x00008094 # program text (code) segment base ld_text_bound 0x0000c54c # program text (code) segment bound ld_text_size 17592 # program text (code) size in bytes ld_data_base 0x0000c54c # program initialized data segment base ld_data_bound 0x000177d0 # program initialized data segment bound ld_data_size 45700 # program init'ed `.data' and uninit'ed `.bss' size in bytes ld_stack_base 0xc0000000 # program stack segment base (highest address in stack) ld_stack_size 16384 # program initial stack size ld_prog_entry 0x000080b0 # program entry point (initial PC) ld_environ_base 0xbfffc000 # program environment base address address ld_target_big_endian 0 # target executable endian-ness, non-zero if big endian mem.page_count 11 # total number of pages allocated mem.page_mem 44k # total size of memory pages allocated mem.ptab_misses 11 # total first level page table misses mem.ptab_accesses 63794 # total page table accesses mem.ptab_miss_rate 0.0002 # first level page table miss rate
2. 將 GCC, Bintuils 及 uClibc 拉出來重新建置
這個段落主要是給需要修改到編譯器的屠龍人士看的,如果你只是要 ARM Toolchain 或著是要修改 Simulator 的話這段可以直接略過。i. 建立一個要放等一下所有東西的資料夾
mkdir ~/arm-linux-gcc
ii. 把整串 toolchain 拉出來
cp -a buildroot-2012.08/output/host/usr ~/arm-linux-gcc/
iii. 資料夾重新命名為 arm-linux-gcc
mv ~/arm-linux-gcc/usr ~/arm-linux-gcc/arm-linux-gcc
iv. gcc, binutils, uclibc 等 source code 拉出來
cp -a buildroot-2012.08/output/toolchain/gcc-4.5.4 ~/arm-linux-gcc/ cp -a buildroot-2012.08/output/toolchain/uClibc-0.9.31.1/ ~/arm-linux-gcc/ tar -jxf buildroot-2012.08/dl/binutils-2.21.tar.bz2 -C ~/arm-linux-gcc
v. 建立 bulid-* 資料夾準備
cd ~/arm-linux-gcc mkdir build-gcc mkdir build-binutils
vi. 重新 build bintuils
cd build-binutils
vii. 開啟bintuils 的 config log 看一下怎麼下
vim ~/buildroot-2012.08/output/build/host-binutils-2.21/config.log大約在第七行會有類似的東西
$ ./configure --prefix=/home/kito/buildroot-2012.08/output/host/usr --sysconfdir=/home/kito/buildroot-2012.08/output/host/etc --enable-shared --disable-static --disable-multilib --disable-werror --target=arm-unknown-linux-uclibc --disable-shared --enable-static --with-sysroot=/home/kito/buildroot-2012.08/output/host/usr/arm-unknown-linux-uclibc/sysroot
viii. 產生新的 configure 參數
接著把 configure 中所有路徑更新一下, 然後 --sysconfdir 可以拿掉note : 這邊路徑用我家示範,--prefix 跟 --with-sysroot 都要改
../binutils-2.21/configure --prefix=/home/kito/arm-linux-gcc/arm-linux-gcc --enable-shared --disable-static --disable-multilib --disable-werror --target=arm-unknown-linux-uclibc --disable-shared --enable-static --with-sysroot=/home/kito/arm-linux-gcc/arm-linux-gcc /arm-unknown-linux-uclibc/sysroot
ix. 建置並安裝 buildroot
make -j8 make install
x. 重新 build gcc
cd build-gcc
xi. 偷看 buildroot config 怎麼下
~/arm-linux-gcc/arm-linux-gcc/bin/arm-linux-gcc -v應該會吐出下面訊息,看到 Configured with: 那一段,抄過來修改
Using built-in specs. COLLECT_GCC=/home/kito/buildroots/buildroot-2012.08/output/host/usr/bin/arm-linux-gcc COLLECT_LTO_WRAPPER=/home/kito/buildroots/buildroot-2012.08/output/host/usr/libexec/gcc/arm-unknown-linux-uclibc/4.5.4/lto-wrapper Target: arm-unknown-linux-uclibc Configured with: /home/kito/buildroots/buildroot-2012.08/output/toolchain/gcc-4.5.4/configure --prefix=/home/kito/buildroots/buildroot-2012.08/output/host/usr --build=x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu --target=arm-unknown-linux-uclibc --enable-languages=c --with-sysroot=/home/kito/buildroots/buildroot-2012.08/output/host/usr/arm-unknown-linux-uclibc/sysroot --with-build-time-tools=/home/kito/buildroots/buildroot-2012.08/output/host/usr/arm-unknown-linux-uclibc/bin --disable-__cxa_atexit --enable-target-optspace --disable-libquadmath --disable-libgomp --with-gnu-ld --disable-libssp --disable-multilib --disable-tls --enable-shared --with-gmp=/home/kito/buildroots/buildroot-2012.08/output/host/usr --with-mpfr=/home/kito/buildroots/buildroot-2012.08/output/host/usr --with-mpc=/home/kito/buildroots/buildroot-2012.08/output/host/usr --disable-nls --enable-threads --disable-decimal-float --with-float=soft --with-abi=apcs-gnu --disable-largefile --with-pkgversion='Buildroot 2012.08' --with-bugurl=http://bugs.buildroot.net/ Thread model: posix gcc version 4.5.4 (Buildroot 2012.08)
xii. 產生新的 gcc 的 configure 參數
接著把 configure 中所有路徑更新一下, 然後 --with-bugurl, --with-pkgversion 可以拿掉 build 跟 host 也可以拔掉,它會自己抓,這樣整串指令就不會太長note1 : mpfr, gmp, mpc 如果你系統有裝的話可以使用系統的就好, 如果使用系統的話--with-gmp --with-mpfr --with-mpc 這三個可以拔掉
note2 : 這邊路徑用我家示範,--prefix --with-sysroot 跟 --with-build-time-tools= 都要改
note3 : 需要 g++ 的話,把--enable-languages=c 改成 --enable-languages=c,c++
../gcc-4.5.4/configure --prefix=/home/kito/arm-linux-gcc/arm-linux-gcc --target=arm-unknown-linux-uclibc --enable-languages=c --with-sysroot=/home/kito/arm-linux-gcc/arm-linux-gcc/arm-unknown-linux-uclibc/sysroot --with-build-time-tools=/home/kito/arm-linux-gcc/arm-linux-gcc/arm-unknown-linux-uclibc/bin --disable-__cxa_atexit --enable-target-optspace --disable-libquadmath --disable-libgomp --with-gnu-ld --disable-libssp --disable-multilib --disable-tls --enable-shared --disable-nls --enable-threads --disable-decimal-float --with-float=soft --with-abi=apcs-gnu --disable-largefile
xiii. 建置 gcc !
make! 另外注意一下 gcc 4.4 不支援 make -jx 的功能make -j8 make install
xiv. 檢查 gcc
~/arm-linux-gcc/arm-linux-gcc/bin/arm-linux-gcc -v輸出會跟第一次很像但 Configured with: 後面已經換成新的參數,這樣就代表有覆蓋掉舊的了
Using built-in specs. COLLECT_GCC=/home/kito/arm-linux-gcc/arm-linux-gcc/bin/arm-linux-gcc COLLECT_LTO_WRAPPER=/home/kito/arm-linux-gcc/arm-linux-gcc/libexec/gcc/arm-unknown-linux-uclibc/4.5.4/lto-wrapper Target: arm-unknown-linux-uclibc Configured with: ../gcc-4.5.4/configure --prefix=/home/kito/arm-linux-gcc/arm-linux-gcc --target=arm-unknown-linux-uclibc --enable-languages=c --with-sysroot=/home/kito/arm-linux-gcc/arm-linux-gcc/arm-unknown-linux-uclibc/sysroot --with-build-time-tools=/home/kito/arm-linux-gcc/arm-linux-gcc/arm-unknown-linux-uclibc/bin --disable-__cxa_atexit --enable-target-optspace --disable-libquadmath --disable-libgomp --with-gnu-ld --disable-libssp --disable-multilib --disable-tls --enable-shared --disable-nls --enable-threads --disable-decimal-float --with-float=soft --with-abi=apcs-gnu --disable-largefile : (reconfigured) ../gcc-4.5.4/configure --prefix=/home/kito/arm-linux-gcc/arm-linux-gcc --target=arm-unknown-linux-uclibc --enable-languages=c,c++ --with-sysroot=/home/kito/arm-linux-gcc/arm-linux-gcc/arm-unknown-linux-uclibc/sysroot --with-build-time-tools=/home/kito/arm-linux-gcc/arm-linux-gcc/arm-unknown-linux-uclibc/bin --disable-__cxa_atexit --enable-target-optspace --disable-libquadmath --disable-libgomp --with-gnu-ld --disable-libssp --disable-multilib --disable-tls --enable-shared --disable-nls --enable-threads --disable-decimal-float --with-float=soft --with-abi=apcs-gnu --disable-largefile Thread model: posix gcc version 4.5.4 (GCC)
xv. 重新 build uClibc
cd ~/arm-linux-gcc/uClibc-0.9.31.1
xvi. 將 buildroot 中 linux header 複製過來
cp -a ~/buildroot-2012.08/output/toolchain/linux/ .
xvii. 更新 uClibc 組態
vim .config# 修改以下地方
KERNEL_HEADERS="/home/kito/buildroot-2012.08/output/toolchain/linux/include" 改成 KERNEL_HEADERS="/home/kito/arm-linux-gcc/uClibc-0.9.31.1/linux/include" RUNTIME_PREFIX="/" 改成 RUNTIME_PREFIX="/home/kito/arm-linux-gcc/arm-linux-gcc/" DEVEL_PREFIX="/usr/" 改成 DEVEL_PREFIX="/home/kito/arm-linux-gcc/arm-linux-gcc/" CROSS_COMPILER_PREFIX="/home/kito/buildroots/buildroot-2012.08/output/host/usr/bin/arm-unknown-linux-uclibc-" 改成 CROSS_COMPILER_PREFIX="/home/kito/arm-linux-gcc/arm-linux-gcc/bin/arm-unknown-linux-uclibc-"# 然後存檔離開
xviii. 重新 build uClibc !
make -j8 make install
xix. 往後更動 gcc 步驟
大功告成,往後如果有更動到 gccuClibc 必須清掉重新 build 一次
make clean make -j8 make install