Programowanie systemów wbudowanych
Transkrypt
Programowanie systemów wbudowanych
Programowanie systemów wbudowanych OS Linux - Toolchain Iwona Kochańska Katedra Systemów Elektroniki Morskiej WETI PG March 30, 2016 Elementy wbudowanego OS Linux Toolchain kompilator i inne narzdzia do tworzenia kodu dla urzadze ˛ ń Bootloader inicjalizuje platform sprz˛etowa˛ oraz ładuje jadro ˛ systemu Kernel serce systemu, zarzadza ˛ zasobami i komunikuje sie˛ ze sprz˛etem Root filesystem GUT – Intel 2015/16 biblioteki i programy uruchamiane w systemie 2/36 Co to jest toolchain? Toolchain - zestaw narz˛edzi do kompilacji kodu źródłowego do plików wykonywalnych na platformie docelowej: I kompilator I linker I biblioteki współdzielone Za pomoca˛ narz˛edzi toolchain można zbudować podstawowe elementy OS dla systemu wbudowanego: I program rozruchowy (bootloader) I jadro ˛ systemu (kernel) I system plików (root filesystem) GUT – Intel 2015/16 3/36 Co to jest toolchain? I Toolchain powinien kompilować kod źródłowy w jezyku ˛ asemblera, C i C++ (w tych jezykach ˛ napisane sa˛ kody źródłowe OS linux) I Toolchain Linux składa sie˛ z elementów GNU project (http://www.gnu.org) I Alternatywa - kompilator Clang i zwiazany ˛ z nim LLVM project (http://llvm.org) GUT – Intel 2015/16 4/36 Elementy toolchain Binutils narz˛edzia binarne: assembler, linker, ld GCC kompilatory C i innych jezyków: ˛ C++, Objective-C, ObjectiveC++, 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 5/36 Toolchain Podstawowe definicje: I build: platforma lokalna, na której realizowana jest kompilacja (na przykład PC z dystrybucja˛ Debiana) I target: platforma docelowa (na przykład Raspberry Pi) I host: OS dostarczajacy ˛ wirtualnego środowiska I guest: OS w środowisku wirtualnym GUT – Intel 2015/16 6/36 Rodzaje toolchain-ów I Natywny (np. w komputerach typu desktop) build machine arch. A I ⇒ host machine arch. A ⇒ target machine arch. A Kompilacja skrośna (cross-compilation) build machine arch. A GUT – Intel 2015/16 ⇒ host machine arch. A 7/36 ⇒ target machine arch. B Rodzaje toolchain-ów I Natywny skrośny (cross-native) build machine arch. A I ⇒ host machine arch. B ⇒ target machine arch. B ⇒ host machine arch. B ⇒ target machine arch. C Canadian build machine arch. A GUT – Intel 2015/16 8/36 Kompilacja skrośna Dwa podstawowe problemy kompilacji skrośnej: I I Wszystkie pliki nagłówkowe i biblioteki C/C++ dla platformy docelowej musza˛ być dostepne ˛ na platformie kompilujacej ˛ (build). Kompilator powinien wygenerować kod właściwy dla platformy docelowej (target). GUT – Intel 2015/16 9/36 Architektury CPU Toolchain powinien być dostosowany do właściwości CPU platformy docelowej (target): I Architektury CPU: arm, mips, x86_64, itd. I Big- lub little-endian: niektóre CPU moga˛ pracować w obu trybach, ale kod maszynowy jest inny dla każdego z nich I Wsparcie operacji na liczbach zmiennoprzecinkowych: sprz˛etowe lub programowe I Application Binary Interface (ABI): reguły współpracy (przekazywania parametrów) miedzy ˛ programami, bibliotekami, a systemem operacyjnym. Dotyczy oprogramowania w wersji binarnej. GUT – Intel 2015/16 10/36 Rodzaje ABI dla procesorów ARM I OABI - Old Application Binary Interface (OABI) - nie kontynuowany po roku 2011 I EABI - Extended/Embedded Application Binary Interface (EABI) I I I I dynamiczne linkowanie nie jest wymagane organizacja stosu bardziej kompaktowa niż w systemie ogólnego przeznaczenia rejestry całkowite (ogólnego przeznaczenia) EABIHF - Hard Float Extended Application Binary Interface rejestry zmiennoprzecinkowe GUT – Intel 2015/16 11/36 GNU prefix GNU prefix - złożony z trzech lub czterech elementów oddzielonych myślnikami: I CPU: arm, mips, x86_64, el = little-endian, eb = big-endian; np. armeb = big-endian ARM I Dostawca OS, np. Poky I Jadro, ˛ np. linux I 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−l i n u x −gnu GUT – Intel 2015/16 12/36 Biblioteka C I Interfejs programistyczny Application zdefiniowany jest w jezyku ˛ C (standard POSIX) I Bilbioteka C to implementacja tego interfejsu (do komunikacji programu z jadrem ˛ systemu) C library I Biblioteka C używa wywołań systemowych w celu uzyskania dostepu ˛ do usługi jadra ˛ (przejście miedzy ˛ przestrzenia˛ użytkownika a przestrzenia˛ jadra) ˛ Linux kernel GUT – Intel 2015/16 13/36 Biblioteki C I glibc - standardowa GNU C, najbardziej kompletna implementacja POSIX API I eglibc - wbudowana GLIBC I I I uClibc - C dla mikrokontrolerów I I I łatki do glibc dodajace ˛ opcje konfiguracji i wsparcie dla architektur nie obsługiwanych przez glibc właczona ˛ do glibc poczawszy ˛ od wersji 2.20 zaprojektowana do współpracy z uClinux (Linux dla CPUs bez jednostki zarzadzania ˛ pamieci ˛ a) ˛ obecnie współpracuje z pełnym Linuxem musl libc - nowa biblioteka C dla systemów wbudowanych GUT – Intel 2015/16 14/36 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−g e t i n s t a l l automake b i s o n c h r p a t h f l e x g++ g i t g p e r f gawk l i b e x p a t 1 −dev l i b n c u r s e s 5 −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 nastepnie: ˛ $ $ $ $ $ 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 . / configure make make i n s t a l l GUT – Intel 2015/16 15/36 Crosstool-NG I Wejście do crosstool menu: $ . / c t −ng I Lista przykładowych konfiguracji: $ . / c t −ng l i s t −samples I Wybór konfiguracji: $ . / c t −ng arm−cortex_a8−l i n u x −gnueabi I Zmiany za pomoca˛ menu konfiguracyjnego: $ . / c t −ng menuconfig I Konfiguracja zapisywana jest w pliku .config. Budowa toolchain-a: $ . / c t −ng b u i l d GUT – Intel 2015/16 16/36 Crosstool-NG I Ścieżka do toolchain-a: arm−cortex_a8−l i n u x −gnueabi / b i n / I Dodanie ścieżki do zmiennej PATH: $ PATH = / . . . / arm−cortex_a8−l i n u x −g n u e a b i h f / b i n : $PATH I 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 I Sprawdzenie rodzaju pliku wykonywalnego: $ f i l e helloworld h e l l o w o r l d : ELF 32− b i t LSB executable , ARM, v e r s i o n 1 (SYSV) , d y n a m i c a l l y l i n k e d ( uses shared l i b s ) , f o r GNU/ L i n u x 3 . 1 5 . 4 , not s t r i p p e d GUT – Intel 2015/16 17/36 Crosstool-NG I Sprawdzenie wersji kompilatora: $ arm−cortex_a8−l i n u x −gnueabi−gcc −−v e r s i o n I Sprawdzenie konfiguracji kompilatora: $ arm−cortex_a8−l i n u x −gnueabi−gcc −v I 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 −h e l p GUT – Intel 2015/16 18/36 Crosstool-NG Toolchain sysroot - katalog z folderami dla bibliotek, plików nagłówkowych i innych plików konfiguracyjnych I ścieżka może być ustawiona podczas konfiguracji toolchain-a za pomoca: ˛ −−w i t h −s y s r o o t = lub podczas jego wywołania za pomoca: ˛ −−s y s r o o t = I Sprawdzenie ścieżki domyślnej sysroot: $ arm−cortex_a8−l i n u x −gnueabi−gcc −p r i n t −s y s r o o t GUT – Intel 2015/16 19/36 Crosstool-NG Sysroot zawiera: I lib: objekty współdzielone dla biblioteki C i dynamicznego linkera, I ld-linux usr/lib: archiwym bibliotek statycznych I usr/include: pliki nagłówkowe wszystkich bibliotek I usr/bin: narz˛edzia uruchamiane na maszynie docelowej (np. komenda ldd) I usr/share: pliki niezależne od maszyny docelowej I sbin: zawiera narz˛edzie ldconfig do zarzadzania ˛ cache-owaniem bibliotek współdzielonych GUT – Intel 2015/16 20/36 Narz˛edzia toolchain-a Polecenie addr2line ar as c++filt cpp elfedit g++ gcc gcov gdb gprof GUT – Intel 2015/16 Opis tłumaczy adresy na numery linii 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˛edzie analizy pokrycia kodu (code coverage) GNU debugger narz˛edzie analizy wydajności programu 21/36 Narz˛edzia toolchain-a Polecenie ld nm objcopy objdump ranlib readelf size strings strip GUT – Intel 2015/16 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 22/36 Biblioteka C Cztery główne cz˛eści biblioteki implementuja˛ składowe standardu POSIX: I libc: główna biblioteka (implementacja printf, open, close, read, write) I libm: funkcje matematyczne (cos, exp, log) I libpthread: funkcje zwiazane ˛ z watkami ˛ (nazwy rozpoczynajace ˛ sie˛ od pthread_ ) I librt: rozszerzenie czasu rzeczywistego (obsługa pamieci ˛ 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/36 Biblioteka C I 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 : [ l i b m . so . 6 ] 0x00000001 (NEEDED) Shared l i b r a r y : [ l i b c . so . 6 ] I 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 / l d−l i n u x −armhf . so . 3 ] GUT – Intel 2015/16 24/36 Linkowanie statyczne i dynamiczne Kod biblioteki może być dołaczony ˛ do programu na dwa sposoby: I statycznie - kod wołanych funkcji (i ich powiazania) ˛ jest dołaczany ˛ do pliku wynikowego (wykonywalnego) I 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/36 Biblioteki statyczne Statyczne linkowanie jest przydatne: I gdy budowany system jest mały i składa sie ˛ tylko z elementów BusyBox I gdy program jest uruchamiany bez dostepu ˛ 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 w o r l d −s t a t i c GUT – Intel 2015/16 26/36 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−a r r c l i b t e s t . a t e s t 1 . o t e s t 2 . 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/36 Biblioteki współdzielone Dołaczane ˛ do programu podczas jego wykonywania I Istnieja˛ dzieki ˛ wynalezieniu pamieci ˛ wirtualnej I Pozwalaja˛ efektywnie wykorzystać pamieć, ˛ ponieważ wystarcza tylko jedna kopia danej biblioteki w pamieci ˛ I Łatwo je aktualizować GUT – Intel 2015/16 28/36 Biblioteki współdzielone I 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 pamieci ˛ I 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 bedzie ˛ szukał libtest.so w domyślnej ścieżce /lib lub /usr/lib. I Dołaczenie ˛ innych ścieżek bibliotek współdzielonych - w zmiennej LD_LIBRARY_PATH GUT – Intel 2015/16 29/36 Nazwy bibliotek współdzielonych ldd - przeszukuje standardowa˛ ścieżk˛e bibliotek i pokazuje wersje bibliotek używanych przez dany program ldd helloworld Nazwy bibliotek współdzielonych: I libjpeg.a: biblioteka statyczna (archiwum) I libjpeg.so -> libjpeg.so.8.0.2 : link symboliczny I libjpeg.so.8 -> libjpeg.so.8.0.2: link symboliczny I libjpeg.so.8.0.2: biblioteka współdzielona GUT – Intel 2015/16 30/36 Systemy do kompilacji skrośnej I Proste makefiles, w których sterowanie toolchain-em odbywa sie˛ poprzez zmienna˛ CROSS_COMPILE I Narz˛edzie GNU Autotools I Narz˛edzie CMake (https://cmake.org) GUT – Intel 2015/16 31/36 Makefiles I Do pakietów prostych w kompilacji ( Linux kernel, U-Boot bootloader, Busybox) I Toolchain prefix umieszczany w zmiennej CROSS_COMPILE, np: $ make CROSS_COMPILE=arm−cortex_a8−l i n u x −gnueabi− I Toolchain prefix ustawiany jako zmienna powłoki (shell variable): $ e x p o r t CROSS_COMPILE=arm−cortex_a8−l i n u x −gnueabi− $ make GUT – Intel 2015/16 32/36 GNU Autotools Autotools to zbiór narz˛edzi: I GNU Autoconf I GNU Automake I GNU Libtool I Gnulib Pakiety korzystajace ˛ z Autotools zawieraja˛ skrypt o nazwie configure, który sprawdza zależności i generuje makefiles. I Konfiguracja, budowa i instalacja dowolnego pakietu: $ . / configure $ make $ sudo make i n s t a l l GUT – Intel 2015/16 33/36 GNU Autotools Działanie GNU Autotools można konfigurować za pomoca zmiennych środowiskowych: I CC: polecenie kompilatora C I CFLAGS: dodatkowe flagi kompilatora C I LDFLAGS: dodatkowe flagi linkera (np. -L<lib dir>) I LIBS: dodatkowe biblioteki dla linkera (np. -lm) I CPPFLAGS: flagi preprocesora C/C++ (np. -I<include dir> I CPP: polecenie preprocesora C GUT – Intel 2015/16 34/36 GNU Autotools - kompilacja skrośna I PRZYKŁAD 1: Przygotowanie GNU Autotools do kompilacji skrośnej: $ CC=arm−cortex_a8−l i n u x −gnueabihf−gcc . / c o n f i g u r e I PRZYKŁAD 2: Przygotowanie GNU Autotools do kompilacji skrośnej z ustawieniem maszyny hosta: $CC=arm−cortex_a8−l i n u x −gnueabihf−gcc . / c o n f i g u r e −−h o s t =arm−cortex_a8−l i n u x −g n u e a b i h f I PRZYKŁAD 3: Przygotowanie GNU Autotools do kompilacji skrośnej z ustawieniem maszyny hosta oraz ścieżki instalacji na jako <sysroot>/usr/*: $ CC=arm−cortex_a8−l i n u x −gnueabihf−gcc . / c o n f i g u r e −−h o s t =arm−cortex_a8−l i n u x −g n u e a b i h f −−p r e f i x = / u s r GUT – Intel 2015/16 35/36 Warto przeczytać C. Simmonds. Mastering Embedded Linux Programming. PACKT, 2015. GUT – Intel 2015/16 36/36