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