Linux cross-compile dengan crosstool-ng

Published by Dhani Setiawan on
Filed under: Misc Tags: , ,

Pada artikel ini, saya coba menuliskan langkah-langkah membuat toolchain untuk cross compile program Linux. Os yang dipakai Debian Jessie, tentu saja applicable untuk selain Debian, sedangkan toolchain yang dipakai menggunakan crosstool-ng.

Sebelum ke how-to, ada baiknya dituliskan sedikit penjelasan tentang hal-hal yang berkaitan dengan cross-compile.

Architecture

Setiap CPU (Central Processing Unit) dibuat menurut architecture tertentu, dan setiap architecture berbeda dalam mengeksekusi program [1]. Beberapa contoh cpu architecture yang banyak dipakai diantaranya ada architecture x86, ini merupakan cpu 32 bit yang banyak dipakai di komputer desktop, laptop, serta server. Kemudian ada x86_64, prosesor architecture x86 versi 64 bit. Produk dari Intel dan AMD banyak dipakai untuk dua architecture tersebut.

Kemudian ada architecture ARM, dan seperti x86, ARM adalah 32 bit sedangkan ARM64 untuk yang 64 bit. Prosesor ARM banyak dipakai di system embed dan handheld seperti smartphone, sebagian besar smartphone yang ada saat ini menggunakan cpu ARM.

Selain x86 dan ARM, ada processor architecture yang terkenal di embedded system yaitu MIPS. MIPS banyak dipakai di sistem embed untuk jaringan seperti router dan switch. Beberapa router dan switch seperti Cisco, Ubiquiti dan MikroTik menggunakan MIPS.

Endianness

Setiap cpu, cara mengatur susunan byte (byte order) dalam memory berbeda-beda dan dikelompokkan menjadi dua bagian, little endian dan big endian [2]. Little dan big endian tidak ada pengaruhnya untuk data di memory yang besarnya hanya satu byte (8 bit), bedanya adalah ketika data di memory merupakan multiple byte atau lebih dari satu byte. Big endian (big-end) menyusun dan menginterpretasikan bahwa byte pertama atau byte paling awal adalah byte terbesar, sedangkan litte endian (little-end) sebaliknya.

Contoh untuk tipe data short integer yang besarnya 2 byte. Artinya ada 2 lokasi memory (satu blok memory besarnya 1 byte / 8 bit) yang apabila data dari dua lokasi memory itu dijumlahkan akan membentuk satu data short integer. Byte pertama berisi 0x12 atau 18 dalam desimal, byte kedua berisi 0x34 atau 52 dalam desimal.

Big endian mengartikan byte pertama adalah yang terbesar sehingga kalkulasinya adalah

18 x (2 ^ 8) + 52 = 4660

Sedangkan little endian mengartikan bahwa byte terakhir adalah yang terbesar, pertama yang terkecil, sehingga:

18 + 52 x (2 ^ 8) = 13798

Dari sini terlihat, kalau salah mengartikan endianness, maka hasil program pun akan salah.

Compiled language

Ada dua tipe program yang ada di komputer, yaitu tipe interpreted dan compiled. Program yang termasuk dalam tipe interpreted language tidak perlu di-compile dan biasanya disebut bahasa scripting, beberapa contoh ada bahasa Python, Perl, PHP, dsb.

Berbeda dengan interpreted language, bahasa tipe compiled language harus di-compile sebelum bisa dieksekusi atau dijalankan. Yang termasuk kategori ini diantaranya bahasa C, C++, Pascal, dsb. Program compiled biasanya berjalan lebih cepat daripada tipe interpreted language.

Proses kompilasi adalah proses menerjemahkan bahasa pemrograman yang dipahami manusia kedalam bahasa yang dipahami oleh cpu, program untuk meng-compile program disebut compiler. Berbeda dengan bahasa interpreted yang cukup sekali ditulis dan bisa berjalan di cpu apapun, bahasa compiled harus menyesuaikan tipe cpu yang dipakai.

Cross compile

Dalam proses compile program, ada tiga tipe cpu yang dipakai.

  • Build, Build host adalah cpu dimana compiler dibuat.
  • Host, Host merupakan cpu dimana compiler akan digunakan untuk meng-compile program.
  • Target, Target merupakan cpu dimana program yang sudah di-compile akan berjalan.

Biasanya, untuk compile di komputer x86 dan yang semisalnya, build, host, dan target adalah komputer yang sama. Artinya compiler dibuat di komputer tersebut, kemudian compiler dijalankan di komputer tersebut untuk meng-compile program, dan program yang sudah di-compile akan berjalan di komputer itu.

Sedangkan untuk system embed, prosesnya berbeda. embedded system biasanya dibuat dengan sangat efisien dan resource yang terbatas. Contohnya beberapa jenis router SOHO yang mempunyai prosesor MIPS dengan speed hanya 400 MHz, memory 32 MB, dan storage 64MB. Dengan resource seperti ini tentu saja tidak mungkin kompilasi program dilakukan di router tersebut.

Proses cross-compile adalah proses meng-compile program dengan target cpu arhitecture yang berbeda. Misalnya, program di-compile di mesin Intel x86 seperti laptop atau komputer desktop, tapi program hasil kompilasi akan digunakan di cpu MIPS seperti router. Tools atau program-program yang digunakan untuk melakukan cross-compile disebut toolchain.

Toolchain dibentuk dengan beberapa program, diataranya:

  • binutils, Program untuk memanage program binary, contohnya ld sebagai linker.
  • gcc, koleksi compiler yang dibuat oleh GNU.
  • C library untuk embedded system biasanya menggunakan uclibc meskipun ada juga yang menggunakan glibc.

Proses membuat toolchain merupakan proses yang sangat kompleks dan memerlukan usaha trial and error yang tidak mudah [3]. Thanks to FOSS community, kita tidak perlu melalui proses yang rumit itu. Salah satunya crosstool-ng, tool ini melakukan proses otomasi membuat toolchain seperti patching, compiling, dan linking. Dengan crosstool-ng kita bisa dengan mudah tinggal menjalankan script, memberikan input dan setelah proses selesai, toolchain sudah jadi dan siap digunakan untuk meng-compile program.

Crosstool-ng

Sebelum proses building, kita perlu mengetahui beberapa parameter untuk crosstool-ng, diantaranya cpu architecture, endianness, c library yang dipakai. Untuk case saya beberapa waktu lalu, cpu architecture MIPS 64 bit, c library menggunakan GNU libc versi 2, dan big endian.

Untuk mencari endianness, ketik lscpu di terminal:

Architecture:          mips64
Byte Order:            Big Endian
CPU(s):                2
On-line CPU(s) list:   0,1
Thread(s) per core:    1
Core(s) per socket:    1
Socket(s):             2
L1d cache:             32K
L1i cache:             37K
L2 cache:              1024K

Output dari Byte Order adalah Big Endian.

Pada beberapa system, command lscpu tidak ada sehingga menggunakan cara lain untuk mengetahui endianness

$ ## Big endian output 0
$ echo -n I | od -to2 | awk 'FNR==1{ print substr($2,6,1)}'
$ 0
$
$ ## Output 1 untuk little endian
$ echo -n I | od -to2 | awk 'FNR==1{ print substr($2,6,1)}'
$ 1

Untuk mengetahui cpu architecture dan OS, contoh output untuk notebook saya yang 32 bit

uname -a
Linux DEATH-STAR 3.16.0-4-686-pae #1 SMP Debian 3.16.7-ckt20-1+deb8u1 (2015-12-14) i686 GNU/Linux

Setelah parameter diketahui, berikutnya ke proses build.

Untuk Debian dan sejenisnya, pastikan paket build-essential sudah terinstall

dpkg -l | grep build-essential

# jika belum terinstall
apt-get install build-essential

Download crosstool-ng, versi terakhir saat artikel ini ditulis adalah 1.22

wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.22.0.tar.bz2

Extract tarball dan compile crosstool-ng

tar -xvjf crosstool-ng-1.22.0.tar.bz2
cd crosstool-ng-1.22
./configure --prefix=/usr/local
make

# dengan user root
make install

crosstool-ng sudah terinstall di /usr/local. Selanjutnya buat direktori untuk toolchain. Direktori untuk toolchain dalam contoh ini dinamai crosstool dengan subdirektori build untuk proses build dan subdirektori target untuk toolchain yang sudah siap digunakan.

mkdir -p ~/crosstool/{build,target}
cd ~/crosstool/build
ct-ng list-samples

Dari output sample, yang paling mendekati adalah mipsel-unknown-linux-gnu. mipsel-unknown-linux-gnu adalah contoh konfigurasi untuk target mips little endian dengan c library gnu libc. Karena target dalam kasus ini berbeda, target endianness big endian, maka konfigurasi perlu disesuaikan dengan ct-ng menuconfig

ct-ng show-mipsel-unknown-linux-gnu
ct-ng mipsel-unknown-linux-gnu

ct-ng menuconfig

Di bagian paths and misc options, sesuaikan target direktori sesuai dengan yang sudah dibuat diatas

(${HOME}/crosstool/target) Prefix directory

Di bagian Target Options, ubah endianness ke Big Endian. Pilih exit kemudian save. Setalah itu build toolchain dengan command ct-ng build

ct-ng build

Command ct-ng build akan secara otomatis mendownload tool yang diperlukan seperti binutils, gcc, libc, dsb. ct-ng build juga akan melakukan patching source code dan kemudian compile secara otomatis. Proses ini cukup lama, lebih dari 2 jam dengan prosesor Intel Atom, prosesor yang lebih tinggi seharusnya lebih cepat.

Setelah selesai, toolchain sudah ada di direktori ~/crosstool/target dan sudah bisa digunakan

export PATH=$PATH:$HOME/crosstool/target/bin

# Tes compile program
mips-unknown-linux-gnu-gcc -g -Wall program.c -o program

Program yang sudah di-compile dengan crosstool-ng tinggal di-copy ke mesin target, di-set execution bit nya dan bisa dijalankan.

Refs:

  1. [1] https://en.wikipedia.org/wiki/Central_processing_unit
  2. [2] https://en.wikipedia.org/wiki/Endianness
  3. [3] http://kegel.com/crosstool/crosstool-0.43/buildlogs/
  4. http://crosstool-ng.org/

Sebarkan artikel ini :



Anda tidak perlu repot-repot mengunjungi blog ini.
Silahkan masukkan alamat email dan begitu ada post baru, Saya akan minta robot FeedBurner mengantarkannya ke email inbox Anda.

Delivered by FeedBurner


blog comments powered by Disqus