Toolchain trong Embeded Linux

Khái nim toolchain

Toolchain là tập hợp của các tool dùng để biên dịch source code thành các file executable có thể chạy được trên target device (thiết bị thật). Toolchain bao gồm compiler, linker, các thư viện runtime và một số tool linh tinh khác. Thông thường thì toolchain cho Linux sẽ based trên các thành phần của GNU Project (http://www.gnu.org). Một toolchain về cơ bản sẽ luôn có ít nhất 3 thành phần sau

  • Binutils: là tập hợp các binary tool như as (assembler), ld (linker), ar, objcopy, …
  • Compiler: C compiler và C++ compiler
  • C library: là một bộ các API chuẩn dựa trên POSIX, các ứng dụng sử dụng C library để giao tiếp với kernel

Chúng ta có thể tự build ra toolchain dành riêng cho platform của mình từ source code sử dụng các build system như Buildroot hoặc Yocto Project hoặc cũng có thể lấy trực tiếp binary của toolchain về từ một vendor nào đó (có thể là có phí hoặc free) hoặc cũng có thể được các hardware vendor tặng kèm khi bạn mua phần cứng của họ.

Native toolchain và Cross toolchain

Có thể chia toolchain ra làm 2 loại tùy vào mục đích: Native toolchainCross toolchain.

Native toolchain: Loại toolchain chạy trên hệ thống giống với target device (device dùng để run chương trình build ra bởi toolchain). Thường là toolchain cho desktop dùng để build ra các chương trình chạy trên destop luôn.

Cross toolchain: Loại toolchain này chạy trên hệ thống khác với target device, ví dụ dùng desktop để build ra chương trình chạy trên một thiết bị nhúng khác. Toolchain này giúp cho quá trình phát triển phần mềm trở nên nhanh hơn vì chúng ta có thể develop phần mềm trên desktop PC và load chúng lên chạy trên target device.

Hầu hết software phát triển cho các hệ thống nhúng Linux đều được thực hiện trên desktop PC và dùng cross toolchain để build bởi vì các thiết bị nhúng thường có cấu hình yếu hơn nhiều so với desktop, hạn chế về CPU, memory, storage nên không phù hợp cho development trực tiếp trên đó.

CPU architectures

Các CPU khác nhau sẽ cần các toolchain khác nhau để build ra chương trình có thể run được trên CPU đó. Các yếu tố sau của CPU sẽ ảnh hưởng lên toolchain tương ứng:

  • CPU Architecture: arm, x86_64, mips, …
  • Big endian hay Little endian
  • Floating point support: Không phải processor nào cũng khối hỗ trợ tính toán floating point bằng hardware. Đối với CPU mà processor của nó không có hardware floating point thì toolchain cần cấu hình để dùng thư viện software floating point
  • Application Binary Interface (ABI): có thể là abi, eabi, eabihf

Tên của compiler nói lên điều gì ?

Tên của compiler trong 1 toolchain sẽ cho chúng ta biết một số thông tin về toolchain đó, bao gồm:

  • CPU Architecture
  • Vendor: nhà cung cấp/ nhà phát triển ra toolchain, ví dụ: linaro, buildroot, poky, … hoặc none
  • Kernel: luôn luôn là “linux” với toolchain cho Linux
  • ABI: gnueabi, gnueabihf, uclibcgnueabi, hoặc uclibcgnueabihf

Lưu ý rằng name của compiler có thể không chứa đầy đủ cả 4 thông tin trên.

Ví dụ:

  • aarch64-poky-linux-gcc: cpu architecture là arm 64 bits, vendor là poky, kernel linux
  • gcc-arm-none-eabi: cpu architecture là arm, vendor là none tức là được phát triển bởi community, ABI là eabi (Extended Application Binary Interface)

Sysroot, library, và header files

sysroot là một folder của toolchain, nó chứa các file header, thư viện và các file cấu hình cho việc biên dịch chương trình. Mốt compiler của toolchain support check location của sysroot bằng command line :

Một số folder quan trọng bên trong sysroot:

  • lib: chứa shared objects của C library
  • usr/lib: static library của C library và các 3rd library khác tùy từng toolchain
  • usr/include: header file của tất cả các library
  • usr/bin: một số tool, utilitiy dùng để chạy trên target device

C library

Thư viện C mà mình nói ở phần đầu không phải là một file mà là tập hợp nhiều file, bao gồm 4 thành phần chính

  • libc: Là thành phần chính của C library, implement các POSIX functions như printf, open, close, read, write, …
  • libm: Implement các hàm toán học như cos, exp,log
  • libpthread: Implement tất cả các POSIX function dùng cho thread (có tiền tố là pthread_)
  • librt: Implement các hàm liên quan đến shared memory và asynchronous I/O

 

—  Phạm Minh Tuấn (Shun) —