Programowanie Systemów Wbudowanych

Transkrypt

Programowanie Systemów Wbudowanych
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
Cross-compilation
Programowanie Systemów Wbudowanych
GNU Toolchain i kompilacja skrośna
KSEM WETI PG
April 28, 2015
GNU Toolchain
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
Cross-compilation
I
GNU Toolchain to zbiór narzędzi do budowy i debugowania
programów, zarówno prostych aplikacji jak i elementów jądra
systemów Linux.
I
Toolchain zawiera:
I
I
I
I
I
I
kompilator (GNU compiler),
GNU linker
GNU assembler
GNU debugger
narzędzia do manipulacji zbudowanymi plikami binarnymi (np.
objdump, objcopy, readelf, strip, nm)
glibc - podstawowa biblioteka C w systemach Linux
The Linux Development Process
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
I
Oprogramowanie Linux składa się ze względnie dużej liczby
elementów, łączonych podczas budowania w zbiór małej liczby
plików (wykonywalnych i niewykonywalnych):
I
I
I
I
I
pliki binarne aplikacji
biblioteki (resources)
dokumentacja
dane dla systemu kontroli wersji (source code management,
SCM)
Pliki te są:
I
I
spakowane w opublikowany pakiet dla konkretnej dystrybucji
automatycznie zainstalowane na maszynie docelowej (z
pominięciem etapu pakowania i instalacji pakietu)
Cross-compilation
The Linux Development Process
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
Oprogramowanie Linux dostępne jest w dwóch formach:
I
archiwa źródeł (tarball); standardowy format to .tar.gz lub
.tar.bz2. Rozpakowanie:
tar xvfj toolchains.tar.bz2
lub:
tar xvfz toolchains.tar.gz
I
system kontroli wersji (SCM); SCM automatyzuje proces
pobierania źródeł, nadąża za zmianami oprogramowania,
pobiera niezbędne patche.
Cross-compilation
Konfiguracja lokalnego środowiska
I
Pliki README i INSTALL opisują standardowy proces budowy
programu, obejmujący m.in. konfigurację lokalnego
środowiska
I
I
różne platformy sprzętowe mogą mieć specyficzne ograniczenia
(np. adresowanie pamięci little-endian lub big-endian),
różne dystrybucje Linuxa mogą mieć różne wersje narzędzi i
bibliotek systemowych.
I
Ponadto plik INSTALL powinien definiować sposób instalacji i
deinstalacji programu, wraz z przykładami.
I
GNU Autoconf - narzędzie konfiguracji lokalnego środowiska
w systemach UNIX. Skrypt configure automatycznie
sprawdza, czy w systemie zainstalowane są narzędzia (i jakie
ich wersje) do budowy programu:
./configure [OPTION]... [VAR=VALUE]...
Na przykład:
./configure −−help
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
Cross-compilation
Konfiguracja lokalnego środowiska- GNU Make
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
I
Większość oprogramowania Linux jest budowana przy użyciu
narzędzia GNU make. Program ten czyta skrypt Makefile
(lub makefile), który opisuje:
I
I
I
zależności pomiędzy plikami źródłowymi i plikami wynikowymi,
sposób tworzenia plików wynikowych z plików źródłowych.
Przykład (plik źródeł: hello.c):
$ make
$ ./hello
Hello, World!
I
Makefile może być generowany automatycznie w przypadku
przenośnego oprogramowania przewidzianego do pracy na
różnych platformach. Automatyczny generator makefile
identyfikuje wówczas dostepne narzędzia GNU i od nich
uzależnia zawartosć pliku dla GNU Make (tak jest np. w
przypadku narzędzi do kompilacji skrośnej).
GNU Toolchain
Cross-compilation
Konfiguracja lokalnego środowiska- GNU Make
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
I
Plik Makefile składa się głównie z reguł. Reguła ma
następującą budowę:
CEL: SKADNIKI
KOMENDA
gdzie CEL to nazwa pliku docelowego, który jest tworzony z
plików wymienionych jako SKŁADNIKI, zaś KOMENDA
podaje komendę, która tworzy plik docelowy CEL z plików
składowych SKŁADNIKI
I
Przykład reguły:
hello: hello.c aux.c
gcc hello.c aux.c −o hello
Reguła ta określa sposób tworzenia pliku wykonywalnego
hello z plików hello.c i aux.c
I
Przed komendą musi obowiązkowo wystąpić znak tabulacji.
GNU Toolchain
Cross-compilation
Narzędzia GNU Toolchain
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
Cross-compilation
I
Narzędzia GNU Toolchain automatycznie:
I
I
I
usprawniają powtarzalne cykle kompilacji
zapewniają powtarzalność procesu kompilacji, eliminując
możliwość popełnienia błędu
czynią proces kompilacji (budowy) programu możliwie
najprostszym.
GNU Compiler Collection
I
GNU Compiler Collection (GNU C Compiler):
I
I
1987: Richard Stallman, założyciel GNU Project, postanowił
opracować kompilator, który spełniałby wymagania wolnego
oprogramowania (Free Software).
kompilator GNU C szybko stał się popularny wśrod
programistów wolnego oprogramowania ze względu na swoją
przenośność.
I
Dziś GCC obsługuje różne języki programowania: C i C++,
Ada, Fortran, Objective C, Java.
I
Jądra systemów Linux napisane są w języku C i skompilowane
za pomocą GCC.
I
GCC współpracuje z procesorami o różnych architekturach:
Intel IA32 ("x86"). AMD64, SPARC POWER/PowerPC oraz
rosnącą liczbą procesorów wyspecjalizowanych.
”If it’s commercially available, GCC can probably compile code for it!”
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
Cross-compilation
Kompilacja pojedynczego pliku
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
I
Proces budowy programu:
compile
⇒
assembly
GNU Toolchain
⇒
link
I
Kompilator: tłumaczy kod programu na język maszynowy
(specificzny dla danej rodziny procesorów)
I
Assembler: tłumaczy skompilowane źródło na binarną
reprezentację kodu maszynowego.
I
I
I
nadaje każdej instrukcji maszynowej adres pamięci (ale nie
bezwzględny, raczej symbolicznie lub jako przesunięcie).
tworzy listę wszystkich nierozwiązanych referencji, które
prawdopodobnie zdefiniowane są w innych plikach programu
Linker: łączy kod z plików wygenerowanych przez assembler
(object code) w tzw. plik-kontener, który może być załadowany
do pamięci i wykonany na danej platformie sprzętowej.
Cross-compilation
Programowanie
Systemów
Wbudowanych
Program w pamięci
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
Cross-compilation
pamięć
stos (adresy powrotu i zmienne lokalne)
⇓
⇑
sterta (zmienne dynamiczne)
zmienne statyczne
program
wysoki adres
niski adres
Kompilacja pojedynczego pliku
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
Cross-compilation
I
GCC nie potrafi zbudować wykonywalnego pliku programu,
tłumaczy jedynie kod programu na język maszynowy.
I
Domyślnie GCC wykonuje wszystkie kroki potrzebne do
zbudowania wykonywalnego pliku binarnego, jednak sam
dokonuje jedynie kompilacji. Assembler i Linker to osobne
narzędzia GNU Toolchain, z którymi komunikuje się
kompilator.
I
Zwyczajowo plik wykonywalny dostaje nazwę a.out, chyba że
użytkownik zdefiniuje ją inaczej za pomocą opcji -o
kompilatora gcc.
Kompilacja jednego źródła C
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
Przykład "Hello World"
I
kod źródłowy:
/∗∗ Embedded Systems Programming − Hello World ∗/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char ∗∗argv) {
printf("Hello, World!\n"); return(0); }
I
kompilacja:
$ gcc −o hello hello.c
I
test:
$ ./hello Hello, World!
GNU Toolchain
Cross-compilation
Kompilacja wielu źródeł C
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
I
GNU linker potrafi łączyć ze sobą kilka plików objektów .o w
jeden plik wykonywalny.
I
Przykład:
message.c:
#include <stdio.h>
void goodbye_world(void) { printf("Goodbye, World!\n"); }
Kompilacja message.c:
gcc −c message.c
Sterownik (driver) GCC woła swój wewnętrzny kompilator,
przetwarza kod źródłowy na język maszynowy i przekazuje go
na wejście zewnętrznego assemblera. Assembler tworzy plik z
rozszerzeniem .o, który może być połączony przez GNU linker
z innymi plikami .o.
GNU Toolchain
Cross-compilation
Kompilacja wielu źródeł C
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
main.c:
#include <stdlib.h>
void goodbye_world(void);
int main(int argc, char ∗∗argv) { goodbye_world(); return(0); }
Kompilacja:
gcc −c main.c
Linkowanie:
gcc −o goodbye message.o main.o
Kompilacja i linkowanie w jednym poleceniu:
gcc −o goodbye message.c main.c
Uruchomienie programu:
./goodbye Goodbye, World!
GNU Toolchain
Cross-compilation
Biblioteki zewnętrzne, GLIBC
I
Niemal każda aplikacja Liux używa biblioteki GLIBC
(biblioteka GNU C)
I
I
I
I
I
I
podstawowe operacje wejścia/wyjścia (np. zamknięcie
programu)
cienka wartwa między aplikacją a jądrem Linuxa;
implementacja podstawowych procedur, które byłyby bardziej
kosztowne (złożone), gdyby były w jądrze.
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
Cross-compilation
GCC zakłada, że GLIBC jest domyślnie dodawana do
programu podczas etapu linkowania.
Mimo to do źródeł programu należy dodać pliki nagłówkowe
standardowych bibliotek
Przykład:
#include <stdio.h>
#include <stdlib.h>
#include <math.h> // system math library; part of GLIBC but not automatically inluded
int main(int argc, char ∗∗argv) { ... }
I
Kompilacja i linkowanie:
gcc −o trig −lm trig.c
opcja -lm powoduje, że GCC przeszukuje bibliotekę
matematyczną libm
Biblioteki statyczne a współdzielone
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
Cross-compilation
I
Biblioteki statyczne (static) - podczas kompilacji programu
kod biblioteki statycznej jest umieszczany w wynikowym pliku
binarnym; każda funkcja ma tyle kopii, ile jest programów,
które z niej korzystają.
I
Biblioteki współdzielone (shared) - tylko jedna wersja każdej
funkcji współdzielona między aplikacjami; jest to możliwe
dzięki pamięci wirtualnej - kilka niezależnych aplikacji ma
bezpieczny dostęp do tego samego obszaru pamięci.
Biblioteki statyczne a współdzielone
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
I
Biblioteki współdzielone redukują rozmiar pliku wynikowego
I
Jeśli biblioteka jest współdzielona przez wiele różnych
programów jednocześnie, pozostaje w pamięci i jest
natychmiast dostępna.
I
Biblioteka współdzielona powinna być zbudowana tak, by jej
działanie było niezależne od miejsca w pamięci, do którego
została załadowana:
gcc −fPIC −c message.c
Flaga PIC informuje GCC, by w kodzie maszynowym
programu nie umieszczał odwołań do adresów pamięci.
Utworzenie biblioteki współdzielonej: (plik wyjściowy:
libmessage.so):
gcc −shared −o libmessage.so message.o
GNU Toolchain
Cross-compilation
Biblioteki statyczne a współdzielone
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
I
Użycie biblioteki współdzielonej:
gcc −o goodbye −lmessage −L. main.o
I
I
GCC informuje linkera, że ma połączyć kod pliku main.o z
biblioteką libmessage.so.
flaga -L oznacza, że biblioteki mogą znajdować się w bieżącym
katalogu.
Własna biblioteka współdzielona może być używana tak jak
dostarczana wraz z dystrybucją Linux, pod warnkiem, że
znajduje się w odpowiednim katalogu (np. /usr/lib/)
ld-linux - dynamiczny linker; automatycznie uruchamiany,
gdy uruchamiana jest aplikacja używająca bibliotek
współdzielonych. Poszukuje ich w katalogu /lib i /usr/lib (te
domyślne ścieżki mogą być zmienione w pliku
konfiguracyjnym /etc/ld.so.conf.
GNU Toolchain
Cross-compilation
Biblioteki statyczne a współdzielone
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
I
ldd - przeszukuje domyślne systemowe ścieżki bibliotek
współdzielonych i wypisuje wersje tych bibliotek, używane
przez program:
ldd goodbye
Przykładowy komunikat narzędzia ldd dla programu goodbye:
linux−vdso.so.1 (0x00007ffc8f2bb000)
libmessage.so => not found
libc.so.6 => /lib/x86_64−linux−gnu/libc.so.6 (0x00007fb6d41c1000)
/lib64/ld−linux−x86−64.so.2 (0x00007fb6d458e000)
Przy próbie uruchomienia programu pojawi się błąd:
./goodbye
./goodbye: error while loading shared libraries:
libmessage.so: cannot open shared object file: No such file or directory
GNU Toolchain
Cross-compilation
Biblioteki statyczne a współdzielone
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
Rozwiązanie:
I zmiana ustawień systemowych
I
instalacja libmessage.so w katalogach standardowych
I
ustawienie zmiennej środowiskowej LD_LIBRARY_PATH na
dodatkową ścieżkę bibliotek współdzielonych:
$ export LD_LIBRARY_PATH=$(pwd)
I
po tej operacji ldd zwróci:
linux−vdso.so.1 (0x00007ffd78552000)
libmessage.so => /opt/cpp_examples/libmessage.so (0x00007fc909dd2000)
libc.so.6 => /lib/x86_64−linux−gnu/libc.so.6 (0x00007fc909a07000)
/lib64/ld−linux−x86−64.so.2 (0x00007fc909fd5000)
GNU Toolchain
Cross-compilation
GNU Binutils
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
Cross-compilation
I
GNU Binutils - zbiór narzędzi do tworzenia i obróbki plików
wykonywalnych. Składa się z:
I
I
I
I
I
asemblera (GNU Assembler)
linkera (GNU Linker)
biblioteki obsługi różnych formatów plików z kodem
narzędzi do obróbki plików z kodem (np. objdump)
Binutils jest używany jako back-end przez GCC, ale też wiele
innych programów operujących na kodzie.
GNU Assembler
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
I
Przetwarza kod skompilowany do języka maszynowego w kod
nadający się do wykonania przez konkretny procesor.
I
GNU as obsługuje wiele różnych rodzin mikroprocesorów
(włącznie z Intel IA32, czyli x86)
I
GNU as w danym systemie Linux jest wstępnie
skonfigurowany do pracy z procesorem, na którym pracuje ów
system, jednak można tą konfigurację zmienić
(cross-compilation!)
I
Język maszynowy programu Hello World:
gcc −S hello.c
I
Kompilacja źródła hello.s:
as −o hello.o hello.s
GNU Toolchain
Cross-compilation
GNU Linker
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
I
Aby kod programu był wykonywalny, musi on zostać
sformatowany do postaci ELF (Executable and Linkable
Format), zrozumiałej przez systemy UNIX. Format ten
obowiązuje:
I
I
I
I
pliki wykonywalne,
pliki obiektowe,
bibliotki współdzielone
zrzuty pamięci
I
Za formatowanie do ELF odpowiedziany jest linker.
I
Linker jest również odpowiedzialny za sprawdzenie, czy kod
uruchamiany podczas startu (plik crtbegin.o automatycznie
dołączany do aplikacji) oraz zamykania aplikacji (crtend.o)
znajduje się w prawidłowym miejscu kodu wykonywalnego
Cross-compilation
GNU Linker
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
Cross-compilation
I
objcopy - kopiuje i przekształca pliki obiektowe generowane
przez kompilator
I
objdump - zapisuje zawartość wykonywalnych plików
binarnych w formacie tekstowym; wizualizuje zawartość
plików wykonywalnych.
Przykład:
$ objdump −x −d −S hello
GNU Debugger
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
Cross-compilation
C.D.N.
Programowanie
Systemów
Wbudowanych
Rodzaje toolchain-ów
GNU Toolchain i
kompilacja skrośna
Pojecia podstawowe:
I
I
I
build machine (platforma budująca) - platforma budująca
toolchain
host machine (platforma hosta) - platforma na której działa
toolchain
target machine (platforma docelowa) - platformam, na ktorej
działa skompilowany program.
Rodzaje toolchain-ów
I
Native
build machine
arch. A
I
⇒
host machine
arch. A
⇒
target machine
arch. A
host machine
arch. A
⇒
target machine
arch. B
Cross-compilation
build machine
arch. A
⇒
GNU Toolchain
Cross-compilation
Programowanie
Systemów
Wbudowanych
Rodzaje toolchain-ów
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
Cross-compilation
I
Cross-native - gdy toolchain działa na maszynie docelowej
build machine
arch. A
I
⇒
host machine
arch. B
⇒
target machine
arch. B
⇒
target machine
arch. C
Canadian - rzadko spotykany
build machine
arch. A
⇒
host machine
arch. B
Kompilacja skrośna (cross-compilation)
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
I
Narzędzia do kompilacji skrośnej muszą rozwiązywać dwa
podstawowe problemy:
I
I
I
wszystkie wykorzystywane przez budowany program biblioteki
C/C++ muszą być dostępne na maszynie budującej (build
machine)
kompilator oraz towarzyszące mu narzedzia musi generować
kod możliwy do wykonania na platformie docelowej (target
machine)
Główne elementy kompilacji skrośnej:
I
I
I
toolchain do kompilacji skrośnej
biblioteki C
system plików (root filesystem, sysroot) na maszynie hosta z
bibliotekami i plikami nagłówkowymi obecnymi również na
platformie docelowej
cross-compilation toolchain + sysroot = SDK
GNU Toolchain
Cross-compilation
Narzędzia - Buildroot
Buildroot
I
zbiór skryptów Makefile oraz patch-ów do budowy obrazów
Linux dla systemów wbudowanych.
I
Generuje:
I
I
I
I
toolchain do kompilacji skrośnej
system plików (root filesystem)
obraz jądra (kernel image)
obraz programu rozruchowego (bootloader image)
I
Obsługuje różne architektury procesorów: x86, ARM, MIPS,
PowerPC, etc.
I
Autor: Peter Korsgaard
I
Objęty licencją GNU GENERAL PUBLIC LICENSE V2
I
Wykorzystanie Buildroot do budowy obrazu systemu dla
Raspberry Pi:
http://www.xappsoftware.com/wordpress/2013/06/06/how-tocreate-a-buildroot-environment-for-raspberry-pi/
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
Cross-compilation
Narzędzia - Crosstool-NG
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
Cross-compilation
Crosstool-NG
I
I
I
Bardziej elastyczny (skalowalny) od Buildroot
Strona: http://crosstool-ng.org
Wykorzystanie Crosstool-NG do budowy kompilatora C i C++
dla Raspberry Pi:
http://www.kitware.com/blog/home/post/426
Narzędzia - Eclipse
Programowanie
Systemów
Wbudowanych
GNU Toolchain i
kompilacja skrośna
GNU Toolchain
Cross-compilation
Eclipse
I
Eclipse + konfiguracja + Toolchain dla Intel Galileo:
https://software.intel.com/en-us/iot/downloads
I
Wykorzystanie Eclipse do kompilacji skrośnej dla Raspberry Pi:
http://hertaville.com/2012/09/28/development-environmentraspberry-pi-cross-compiler/

Podobne dokumenty