Programowanie Systemów Wbudowanych OS Linux - Toolchain Iwona Kochańska Katedra Systemów Elektroniki Morskiej WETI PG
Co to jest toolchain? Toolchain - zestaw narzędzi do kompilacji kodu źródłowego do plików wykonywalnych na platformie docelowej: kompilator linker biblioteki współdzielone Za pomoca narzędzi toolchain można zbudować podstawowe elementy OS dla systemu wbudowanego: program rozruchowy (bootloader) jadro systemu (kernel) system plików (root filesystem) GUT Intel 2015/16 2/33
Co to jest toolchain? Toolchain powinien kompilować kod źródłowy w języku asemblera, C i C++ (w tych językach napisane sa kody źródłowe OS linux) Toolchain Linux składa się z elementów GNU project (http://www.gnu.org) Alternatywa - kompilator Clang i zwi azany z nim LLVM project (http://llvm.org) GUT Intel 2015/16 3/33
Elementy toolchain Binutils narzędzia binarne: assembler, linker, ld GCC kompilatory C i innych języków: C++, Objective-C, Objective- C++, Java, Fortran, Ada, i Go Biblioteka C ustandaryzowane API zgodne ze specyfikacja POSIX (podstawowe API jadra OS)... oraz kopia plików nagłówkowych jadra Linuxa. GUT Intel 2015/16 4/33
Toolchain Podstawowe definicje: build: platforma lokalna, na której realizowana jest kompilacja (na przykład PC z dystrybucja Debiana) target: platforma docelowa (na przykład Raspberry Pi) host: OS dostarczajacy wirtualnego środowiska guest: OS w środowisku wirtualnym GUT Intel 2015/16 5/33
Rodzaje toolchain-ów Natywny (np. w komputerach typu desktop) build machine host machine target machine arch. A arch. A arch. A Kompilacja skrośna (cross-compilation) build machine host machine target machine arch. A arch. A arch. B GUT Intel 2015/16 6/33
Rodzaje toolchain-ów Natywny skrośny (cross-native) build machine host machine target machine arch. A arch. B arch. B Canadian build machine host machine target machine arch. A arch. B arch. C GUT Intel 2015/16 7/33
Kompilacja skrośna Dwa podstawowe problemy kompilacji skrośnej: Wszystkie pliki nagłówkowe i biblioteki C/C++ dla platformy docelowej musza być dostępne na platformie kompilujacej (build). Kompilator powinien wygenerować kod właściwy dla platformy docelowej (target). GUT Intel 2015/16 8/33
Architektury CPU Toolchain powinien być dostosowany do właściwości CPU platformy docelowej (target): Architektury CPU: arm, mips, x86_64, itd. Big- lub little-endian: niektóre CPU moga pracować w obu trybach, ale kod maszynowy jest inny dla każdego z nich Wsparcie operacji na liczbach zmiennoprzecinkowych: sprzętowe lub programowe Application Binary Interface (ABI): konwencja przekazywania parametrów między wywołaniami funkcji GUT Intel 2015/16 9/33
Rodzaje ABI dla procesorów ARM OABI - Old Application Binary Interface (OABI) - nie kontynuowany po roku 2011 EABI - Extended Application Binary Interface (EABI) - rejestry ogólnego przeznaczenia (całkowitoliczbowe) EABIHF - Hard Float Extended Application Binary Interface - rejestry zmiennoprzecinkowe GUT Intel 2015/16 10/33
GNU prefix GNU prefix - złożony z trzech lub czterech elementów oddzielonych myślnikami: CPU: arm, mips, x86_64, el = little-endian, eb = big-endian; np. armeb = big-endian ARM Dostawca OS, np. poky Jadro, np. linux OS: nazwa przestrzeni użytkownika (gnu lub uclibc gnu). Może być dołaczony rodzaj ABI (gnueabi, gnueabihf, uclibcgnueabi, lub uclibcgnueabihf). $ gcc dumpmachine x86_64 linux gnu GUT Intel 2015/16 11/33
Instalacja toolchain-a dla ARM (RaspberryPi) Pobranie źródeł: cd katalog g i t clone h t t p s : / / g i t h u b. com / r a s p b e r r y p i / t o o l s Dodanie ścieżki do kompilatora skrośnego do pliku ~/.bashrc: export PATH=$PATH: katalog / r a s p b e r r y p i / t o o l s / arm bcm2708 / gcc l i n a r o arm l i n u x gnueabihf raspbian / bin GUT Intel 2015/16 12/33
Biblioteka C Application C library Linux kernel Interfejs programistyczny do OS Unix zdefiniowany jest w języku C (standard POSIX) Bilbioteka C to implementacja tego interfejsu (do komunikacji programu z jadrem systemu) Biblioteka C używa wywołań systemowych w celu uzyskania dostępu do usługi jadra (przejście między przestrzenia użytkownika a przestrzenia jadra) GUT Intel 2015/16 13/33
Biblioteki C glibc - standardowa GNU C, najbardziej kompletna implementacja POSIX API eglibc - wbudowana GLIBC; łatki do glibc dodajace opcje konfiguracji i wsparcie dla architektur nie obsługiwanych przez glibc; właczona do glibc poczawszy od wersji2.20 uclibc - C dla mikrokontrolerów; zaprojektowana do współpracy z uclinux (Linux dla CPUs bez jednostki zarzadzania pamięcia), obecnie współpracuje z pełnym Linuxem musl libc - nowa biblioteka C dla systemów wbudowanych GUT Intel 2015/16 14/33
Crosstool-NG Crosstool-NG (2007) - buduje wersje stand-alone toolchain-a do kompilacji skrośnej ze źródeł SoC lub od dostawcy platformy Potrzebne pakiety: $ sudo apt get i n s t a l l automake bison chrpath f l e x g++ g i t gperf gawk l i b e x p a t 1 dev libncurses5 dev l i b s d l 1.2 dev l i b t o o l python2.7 dev t e x i n f o Pobranie źródeł z http://crosstool-ng.org/download/crosstool-ng, a następnie: $ t a r x f c r o s s t o o l ng 1.9.3. t a r. bz2 $ cd c r o s s t o o l ng 1.9.3 $. / c o n f i g u r e $ make $ make i n s t a l l GUT Intel 2015/16 15/33
Crosstool-NG Wejście do crosstool menu: $. / ct ng Lista przykładowych konfiguracji: $. / ct ng l i s t samples Wybór konfiguracji: $. / ct ng arm cortex_a8 l i n u x gnueabi Zmiany za pomoca menu konfiguracyjnego: $. / ct ng menuconfig Konfiguracja zapisywana jest w pliku.config. Budowa toolchain-a: $. / ct ng b u i l d GUT Intel 2015/16 16/33
Crosstool-NG Ścieżka do toolchain-a: arm cortex_a8 l i n u x gnueabi / bin / Dodanie ścieżki do zmiennej PATH: $ PATH = /... / arm cortex_a8 l i n u x gnueabihf / bin :$PATH Kompilacja helloworld.c: $ arm cortex_a8 l i n u x gnueabihf gcc h e l l o w o r l d. c o h e l l o w o r l d Sprawdzenie rodzaju pliku wykonywalnego: $ f i l e h e l l o w o r l d h e l l o w o r l d : ELF 32 b i t LSB executable, ARM, version 1 (SYSV), dynamically l i n k e d ( uses shared l i b s ), f o r GNU/ Linux 3. 1 5. 4, not s t r i p p e d GUT Intel 2015/16 17/33
Crosstool-NG Sprawdzenie wersji kompilatora: $ arm cortex_a8 l i n u x gnueabi gcc version Sprawdzenie konfiguracji kompilatora: $ arm cortex_ a8 l i n u x gnueabi gcc v Lista opcji kompilatora zależnych od architektury maszyny docelowej: $ arm cortex_a8 l i n u x gnueabihf gcc t a r g e t help GUT Intel 2015/16 18/33
Crosstool-NG Toolchain sysroot - katalog z podkatalogami dla bibliotek, plików nagłówkowych i innych plików konfiguracyjnych ścieżka może być ustawiona podczas konfiguracji toolchain-a za pomoca: with sysroot= lub podczas jego wywołania za pomoca: sysroot= Sprawdzenie ścieżki domyślnej sysroot: $ arm cortex_a8 l i n u x gnueabi gcc p r i n t sysroot GUT Intel 2015/16 19/33
Crosstool-NG Sysroot zawiera: lib: objekty współdzielone dla biblioteki C i dynamicznego linkera, ld-linux usr/lib: archiwym bibliotek statycznych usr/include: pliki nagłówkowe wszystkich bibliotek usr/bin: narzędzia uruchamiane na maszynie docelowej (np. komenda ldd) usr/share: pliki niezależne od maszyny docelowej sbin: zawiera narzędzie ldconfig do zarz adzania cache-owaniem bibliotek współdzielonych GUT Intel 2015/16 20/33
Narzędzia toolchain-a Polecenie addr2line ar as c++filt cpp elfedit g++ gcc gcov gdb gprof Opis tłumaczy adresy (pl. wykonywalny) na numery linii (kod źródło tworzy biblioteki statyczne GNU assembler przetwarza symbole C++ i Java C preprocessor edycja nagłówka pliku ELF front-end GNU C++ front-end GNU C narzędzie analizy pokrycia kodu (code coverage) GNU debugger narzędzie analizy wydajności programu GUT Intel 2015/16 21/33
Narzędzia toolchain-a Polecenie ld nm objcopy objdump ranlib readelf size strings strip Opis GNU linker wyświetla nazwy symboliczne z plików wynikowych kopiuje i tłumaczy pliki objektowe wyświetla informacje z plików obiektowych tworzy lub modyfikuje indeks bibliotek statycznych wyświetla inforamcje o plikach ELF lista rozmiarów sekcji i całkowity rozmiar wyświetla łańcuchy ( drukowalne ) z pliku usuwa symbole z plików wynikowych GUT Intel 2015/16 22/33
Biblioteka C Cztery główne części biblioteki implementuja składowe standardu POSIX: libc: główna biblioteka (implementacja printf, open, close, read, write) libm: funkcje matematyczne (cos, exp, log) libpthread: funkcje zwiazane z watkami (nazwy rozpoczynajace się od pthread_ ) librt: rozszerzenie czasu rzeczywistego (obsługa pamięci współdzielonej i asynchronicznego I/O) libc jest linkowana zawsze, pozostałe musza być dodane za pomoca opcji -l arm cortex_ a8 l i n u x gnueabihf gcc myprog. c o myprog lm GUT Intel 2015/16 23/33
Biblioteka C Jakie biblioteki zostały dołaczone? $ arm cortex_a8 l i n u x gnueabihf r e a d e l f a myprog grep " Shared l i b r a r y " 0x00000001 (NEEDED) Shared l i b r a r y : [ libm. so. 6 ] 0x00000001 (NEEDED) Shared l i b r a r y : [ l i b c. so. 6 ] Jaki linker jest wołany podczas działania programu? (run-time linker): $ arm cortex_a8 l i n u x gnueabihf r e a d e l f a myprog grep " program i n t e r p r e t e r " [ Requesting program i n t e r p r e t e r : / l i b / ld l i n u x armhf. so. 3 ] GUT Intel 2015/16 24/33
Linkowanie statyczne i dynamiczne Kod biblioteki może być dołaczony do programu na dwa sposoby: statycznie - kod wołanych funkcji (i ich powiazania) jest dołaczany do pliku wynikowego (wykonywalnego) dynamicznie - w pliku wynikowym sa referencje do funkcji bibliotecznych, ale faktyczne dołaczanie ich kodu ma miejsce podczas wykonywania programu GUT Intel 2015/16 25/33
Biblioteki statyczne Statyczne linkowanie jest przydatne: gdy budowany system jest mały i składa się tylko z elementów BusyBox gdy program jest uruchamiany bez dostępu do systemu plików z bibliotekami runtime Linkowanie tylko bibliotek statycznych: $ arm cortex_ a8 l i n u x gnueabihf gcc s t a t i c h e l l o w o r l d. c o h e l l o world s t a t i c GUT Intel 2015/16 26/33
Biblioteki statyczne Tworzenie biblioteki statycznej: $ arm cortex_a8 l i n u x gnueabihf gcc c t e s t 1. c $ arm cortex_a8 l i n u x gnueabihf gcc c t e s t 2. c $ arm cortex_a8 l i n u x gnueabihf ar rc l i b t e s t. a t e s t 1. o Linkowanie libtest do programu helloworld: $ arm cortex_a8 l i n u x gnueabihf gcc h e l l o w o r l d. c l t e s t L.. / l i b s I.. / l i b s o h e l l o w o r l d GUT Intel 2015/16 27/33
Biblioteki współdzielone Dołaczane do programu podczas jego wykonywania Istnieja dzięki wynalezieniu pamięci wirtualnej Pozwalaja efektywnie wykorzystać pamięć, ponieważ wystarcza tylko jedna kopia danej biblioteki w pamięci Łatwo je aktualizować GUT Intel 2015/16 28/33
Biblioteki współdzielone Stworzenie biblioteki współdzielonej: $ arm cortex_a8 l i n u x gnueabihf gcc fpic c t e s t 1. c $ arm cortex_a8 l i n u x gnueabihf gcc fpic c t e s t 2. c $ arm cortex_ a8 l i n u x gnueabihf gcc shared o l i b t e s t. so t e s t 1. o t e s t 2. o Flaga PIC informuje GCC, by generował kod bez referencji do konkretnych miejsc w pamięci Dołaczenie libtest do programu helloworld: $ arm cortex_a8 l i n u x gnueabihf gcc h e l l o w o r l d. c l t e s t L.. / l i b s I.. / l i b s o h e l l o w o r l d Linker będzie szukał libtest.so w domyślnej ścieżce /lib lub /usr/lib. Dołaczenie innych ścieżek bibliotek współdzielonych - w zmiennej LD_LIBRARY_PATH GUT Intel 2015/16 29/33
Nazwy bibliotek współdzielonych ldd - przeszukuje standardowa ścieżkę bibliotek i pokazuje wersje bibliotek używanych przez dany program ldd h e l l o w o r l d Nazwy bibliotek współdzielonych: libjpeg.a: biblioteka statyczna (archiwum) libjpeg.so -> libjpeg.so.8.0.2 : link symboliczny do dynamicznego linkowania libjpeg.so.8 -> libjpeg.so.8.0.2: link symboliczny do ładowania biblioteki podczas działania programu libjpeg.so.8.0.2: biblioteka współdzielona GUT Intel 2015/16 30/33
Systemy do kompilacji skrośnej Proste makefiles, w których sterowanie toolchain-em odbywa się poprzez zmienna CROSS_COMPILE Narzędzie GNU Autotools CMake (https://cmake.org) GUT Intel 2015/16 31/33
Makefiles Do pakietów łatwych w kompilacji ( Linux kernel, U-Boot bootloader, Busybox) Toolchain prefix umieszczany w zmiennej CROSS_COMPILE, np: $ make CROSS_COMPILE=arm cortex_ a8 l i n u x gnueabi Toolchain prefix ustawiany jako zmienna powłoki (shell variable): $ export CROSS_COMPILE=arm cortex_a8 l i n u x gnueabi $ make GUT Intel 2015/16 32/33
GNU Autotools Autotools to zbiór narzędzi: GNU Autoconf GNU Automake GNU Libtool Gnulib Pakiety korzystajace z Autotools zawieraja skrypt o nazwie configure, który sprawdza zależności i generuje makefiles. Konfiguracja, budowa i instalacja pakietu: $. / c o n f i g u r e $ make $ sudo make i n s t a l l GUT Intel 2015/16 33/33