KPiSW_OS Linux1

Transkrypt

KPiSW_OS Linux1
Komputery Przemysłowe i Systemy
Wbudowane
OS Linux w wystemach wbudowanych
Iwona Kochańska
Katedra Systemów Elektroniki Morskiej
WETI PG
October 5, 2016
1/67
Systemy wbudowane - OS
2/67
Systemy wbudowane - jezyki
˛
programowania
3/67
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
biblioteki i programy
uruchamiane w systemie
4/67
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)
5/67
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)
6/67
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
ustandaryzowane API zgodne
ze specyfikacja˛ POSIX (podstawowe API jadra
˛
OS)
Biblioteka
C
... oraz kopia plików nagłówkowych jadra
˛
Linuxa.
7/67
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
8/67
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
9/67
⇒
host machine
arch. A
⇒
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
10/67
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).
11/67
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.
12/67
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
13/67
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
14/67
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
15/67
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
16/67
Outline
Toolchain
Kompilacja natywna
Kompilacja skrośna
Bootloader
17/67
GNU Compiler Collection
I
GNU Compiler Collection (GNU C Compiler):
I
I
I
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ł sie˛ popularny wśrod programistów
wolnego oprogramowania ze wzgledu
˛
na swoja˛ przenośność.
Dziś GCC obsługuje różne jezyki
˛
programowania: C i C++, Ada,
Fortran, Objective C, Java.
Jadra
˛
systemów Linux napisane sa˛ w jezyku
˛
C i skompilowane
za pomoca˛ GCC.
GCC współpracuje z procesorami o różnych architekturach: Intel
IA32 ("x86"). AMD64, SPARC POWER/PowerPC oraz rosnac
˛ a˛
liczba˛ procesorów wyspecjalizowanych.
”If it’s commercially available,
18/67 GCC can probably compile code for it!”
Kompilacja pojedynczego pliku
I
Proces budowy programu:
compile
⇒
assembly
⇒
link
I
Kompilator: tłumaczy kod programu na jezyk
˛
maszynowy
(specificzny dla danej rodziny procesorów)
I
Assembler: tłumaczy skompilowane źródło na binarna˛
reprezentacje˛ kodu maszynowego.
I
I
I
nadaje każdej instrukcji maszynowej adres pamieci
˛ (ale nie
bezwzgledny,
˛
raczej symbolicznie lub jako przesuniecie).
˛
tworzy liste˛ wszystkich nierozwiazanych
˛
referencji, które
prawdopodobnie zdefiniowane sa˛ w innych plikach programu
Linker: łaczy
˛
kod z plików wygenerowanych przez assembler
(object code) w tzw. plik-kontener, który może być załadowany
do pamieci
˛ i wykonany na danej platformie sprz˛etowej.
19/67
Program w pamieci
˛
pamieć
˛
stos (adresy powrotu i zmienne lokalne)
⇓
wysoki adres
⇑
sterta (zmienne dynamiczne)
zmienne statyczne
program
niski adres
20/67
Kompilacja
I
Domyślnie GCC wykonuje wszystkie kroki potrzebne do
zbudowania wykonywalnego pliku binarnego, jednak sam
dokonuje jedynie kompilacji. Assembler i Linker to osobne
narz˛edzia GNU Toolchain, z którymi komunikuje sie˛ kompilator.
I
Zwyczajowo plik wykonywalny dostaje nazwe˛ a.out, chyba że
użytkownik zdefiniuje ja˛ inaczej za pomoca˛ opcji -o kompilatora
gcc.
21/67
Kompilacja jednego źródła C
Przykład "Hello World"
I
kod źródłowy:
/ ∗ ∗ Embedded Systems Programming − H e l l o World ∗ /
# i n c l u d e < s t d i o . h>
# i n c l u d e < s t d l i b . h>
i n t main ( i n t argc , char ∗∗ argv ) {
p r i n t f ( " H e l l o , World ! \ n " ) ; r e t u r n ( 0 ) ; }
I
kompilacja:
$ gcc −o h e l l o h e l l o . c
I
test:
$ . / hello
H e l l o , World !
22/67
Kompilacja wielu źródeł C
I
GNU linker potrafi łaczyć
˛
ze soba˛ kilka plików objektów .o w
jeden plik wykonywalny.
I
Przykład:
message.c:
# i n c l u d e < s t d i o . h>
v o i d goodbye_world ( v o i d ) { p r i n t f ( " Goodbye , World ! \ n "
Kompilacja message.c:
gcc −c message . c
Sterownik (driver) GCC woła swój wewnetrzny
˛
kompilator,
przetwarza kod źródłowy na jezyk
˛
maszynowy i przekazuje go na
wejście zewnetrznego
˛
assemblera. Assembler tworzy plik z
rozszerzeniem .o, który może być połaczony
˛
przez GNU linker z
innymi plikami .o.
23/67
Kompilacja wielu źródeł C
goodbye.c:
# i n c l u d e < s t d l i b . h>
v o i d goodbye_world ( v o i d ) ;
i n t main ( i n t argc , char ∗∗ argv ) { goodbye_world ( ) ; r e t u r n
Kompilacja:
gcc −c goodbye . c
Linkowanie:
gcc −o goodbye message . o goodbye . o
Kompilacja i linkowanie w jednym poleceniu:
gcc −o goodbye message . c goodbye . c
Uruchomienie programu:
. / goodbye
Goodbye , World !
24/67
Biblioteki zewnetrzne,
˛
GLIBC
I
Niemal każda aplikacja Liux używa biblioteki GLIBC (biblioteka
GNU C)
I
I
I
podstawowe operacje wejścia/wyjścia (np. zamkniecie
˛
programu)
cienka wartwa miedzy
˛
aplikacja˛ a jadrem
˛
Linuxa;
implementacja podstawowych procedur, które byłyby bardziej
kosztowne (złożone), gdyby były w jadrze.
˛
I
GCC zakłada, że GLIBC jest domyślnie dodawana do programu
podczas etapu linkowania.
I
Mimo to do źródeł programu należy dodać pliki nagłówkowe
standardowych bibliotek
25/67
Biblioteki zewnetrzne,
˛
GLIBC
I
Przykład:
# include < s t d i o . h>
# include < s t d l i b . h>
# include <math . h> / / system math l i b r a r y ; p a r t o f GL
i n t main ( i n t argc , char ∗∗ argv ) { . . . }
I
Kompilacja i linkowanie:
gcc −o t r i g −lm t r i g . c
opcja -lm powoduje, że GCC przeszukuje bibliotek˛e
matematyczna˛ libm
I
Biblioteki systemowej UNIX (Linux) zwykle rozpoczynaja˛ sie˛ od
przedrostka “lib” i znajduja˛ sie˛ w katalogu /lib lub /usr/lib.
26/67
Biblioteki statyczne a współdzielone
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 korzystaja.
˛
I
Biblioteki współdzielone (shared) - tylko jedna wersja każdej
funkcji współdzielona miedzy
˛
aplikacjami; jest to możliwe dzieki
˛
pamieci
˛ wirtualnej - kilka niezależnych aplikacji ma bezpieczny
dostep
˛ do tego samego obszaru pamieci.
˛
I
I
I
Istnieja˛ dzieki
˛ wynalezieniu pamieci
˛ wirtualnej
Pozwalaja˛ efektywnie wykorzystać pamieć,
˛ ponieważ wystarcza
tylko jedna kopia danej biblioteki w pamieci
˛
Łatwo je aktualizować
27/67
Biblioteki statyczne a współdzielone
I
Biblioteki współdzielone redukuja˛ rozmiar pliku wynikowego
I
Jeśli biblioteka jest współdzielona przez wiele różnych
programów jednocześnie, pozostaje w pamieci
˛ i jest natychmiast
dostepna.
˛
I
Biblioteka współdzielona powinna być zbudowana tak, by jej
działanie było niezależne od miejsca w pamieci,
˛ 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 pamieci.
˛
I
Utworzenie biblioteki współdzielonej: (plik wyjściowy:
libmessage.so):
gcc −shared −o libmessage . so message . o
28/67
Biblioteki statyczne a współdzielone
I
Użycie biblioteki współdzielonej:
gcc −o goodbye −lmessage −L . goodbye . o
I
I
GCC informuje linkera, że ma połaczyć
˛
kod pliku main.o z
biblioteka˛ libmessage.so.
flaga -L oznacza, że biblioteki moga˛ znajdować sie˛ w bieżacym
˛
katalogu.
Własna biblioteka współdzielona może być używana tak jak
dostarczana wraz z dystrybucja˛ Linux, pod warnkiem, że
znajduje sie˛ w odpowiednim katalogu (np. /usr/lib/)
ld-linux - dynamiczny linker; automatycznie uruchamiany, gdy
uruchamiana jest aplikacja używajaca
˛ bibliotek współdzielonych.
Poszukuje ich w katalogu /lib i /usr/lib (te domyślne ścieżki moga˛
być zmienione w pliku konfiguracyjnym /etc/ld.so.conf.
29/67
Biblioteki statyczne a współdzielone
I
ldd - przeszukuje domyślne systemowe ścieżki bibliotek
współdzielonych i wypisuje wersje tych bibliotek, używane przez
program:
l d d goodbye
I
Przykładowy komunikat narz˛edzia ldd dla programu goodbye:
l i n u x −vdso . so . 1 ( 0 x00007ffc8f2bb000 )
libmessage . so => n o t found
l i b c . so . 6 => / l i b / x86_64−l i n u x −gnu / l i b c . so . 6 ( 0 x00007
/ l i b 6 4 / l d −l i n u x −x86 −64.so . 2 ( 0 x00007fb6d458e000 )
I
Przy próbie uruchomienia programu pojawi sie˛ bład:
˛
. / goodbye
. / goodbye : e r r o r w h i l e l o a d i n g shared l i b r a r i e s :
libmessage . so : cannot open shared o b j e c t f i l e : No suc
30/67
Biblioteki statyczne a współdzielone
Rozwiazanie:
˛
I
instalacja libmessage.so w katalogach standardowych
I
ustawienie zmiennej środowiskowej LD_LIBRARY_PATH na
dodatkowa˛ ścieżk˛e bibliotek współdzielonych:
e x p o r t LD_LIBRARY_PATH=$ ( pwd )
I
po tej operacji ldd zwróci:
l i n u x −vdso . so . 1 ( 0 x00007ffd78552000 )
libmessage . so => / o p t / cpp_examples / libmessage . so ( 0 x0
l i b c . so . 6 => / l i b / x86_64−l i n u x −gnu / l i b c . so . 6 ( 0 x00007
/ l i b 6 4 / l d −l i n u x −x86 −64.so . 2 ( 0 x00007fc909fd5000 )
31/67
GNU Binutils
I
GNU Binutils - zbiór narz˛edzi do tworzenia i obróbki plików
wykonywalnych. Składa sie˛ z:
I
I
I
I
I
asemblera (GNU Assembler)
linkera (GNU Linker)
biblioteki obsługi różnych formatów plików z kodem
narz˛edzi do obróbki plików z kodem (np. objdump)
Binutils jest używany jako back-end przez GCC, ale też wiele
innych programów operujacych
˛
na kodzie.
32/67
GNU Assembler
I
Przetwarza kod skompilowany do jezyka
˛
maszynowego w kod
nadajacy
˛ sie˛ do wykonania przez konkretny procesor
I
GNU as obsługuje wiele różnych rodzin mikroprocesorów
(włacznie
˛
z Intel IA32, czyli x86)
I
GNU as w danym systemie Linux jest wstepnie
˛
skonfigurowany
do pracy z procesorem, na którym pracuje ów system, jednak
można ta˛ konfiguracje˛ zmienić (cross-compilation!)
I
Jezyk
˛
maszynowy programu Hello World:
gcc −S h e l l o . c
I
Kompilacja źródła hello.s:
as −o h e l l o . o h e l l o . s
33/67
GNU Linker
I
Aby kod programu był wykonywalny, musi on zostać
sformatowany do postaci ELF (Executable and Linkable Format),
zrozumiałej przez systemy UNIX. Format ten obowiazuje:
˛
I
I
I
I
pliki wykonywalne,
pliki obiektowe,
bibliotki współdzielone
zrzuty pamieci
˛
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łaczany
˛
do aplikacji) oraz zamykania aplikacji (crtend.o)
znajduje sie˛ w prawidłowym miejscu kodu wykonywalnego
34/67
GNU Linker
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 h e l l o
35/67
Outline
Toolchain
Kompilacja natywna
Kompilacja skrośna
Bootloader
36/67
Kompilacja skrośna
I
Pobieramy pliki z repozytorium, np:
h t t p s : / / g i t h u b . com / C h r i s t o p h e r 8 3 / arm−cortex_a8−l i n u x −
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 shared37/67l i b s ) , f o r GNU/ L i n u x 3 . 1 5 . 4 ,
Kompilacja skrośna
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
38/67
Kompilacja skrośna
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
39/67
Kompilacja skrośna
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
40/67
Narz˛edzia toolchain-a
Polecenie
addr2line
ar
as
c++filt
cpp
elfedit
g++
gcc
gcov
gdb
gprof
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
41/67
Narz˛edzia 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
42/67
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
43/67
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 ]
44/67
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
45/67
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
46/67
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
47/67
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)
48/67
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
49/67
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
50/67
Uruchamianie systemu Linux
51/67
Co to jest bootloader?
Program rozruchowy
I
inicjalizuje system
I
ładuje jadro
˛
OS do pamieci
˛
Uruchamianie systemu polega
na przejściu kilku faz, w których
coraz wiecej
˛
zasobów jest
dostepnych
˛
dla programu rozruchowego.
52/67
Co to jest bootloader?
I
Ostateczny rezultat pracy bootloader-a to:
I
I
I
I
Dodatkowo bootloader dostarcza trybu serwisowego do:
I
I
I
I
jadro
˛
systemu operacyjnego załadowane do pamieci
˛ RAM
uruchomione środowisko wykonawcze dla jadra
˛
(linia poleceń jadra
˛
systemu)
jadro
˛
systemu dostaje wskaźnik do informacji o platformie
sprz˛etowej
aktualizacji konfiguracji procesu boot-owania,
ładowania nowych obrazów programów rozruchowych do pamieci
˛
diagnostyki
Kiedy jadro
˛
OS rozpoczyna wykonywanie swojego programu,
bootloader nie jest dłużej potrzebny.
53/67
Sekwenca rozruchowa - “old days”
I Bootloader w pamieci
˛ nieulotnej w
wektorze resetu
I pamieć
˛ NOR flash mapowana
bezpośrednio na przestrzeń
adresowa˛
54/67
Sekwenca rozruchowa - współcześnie
Faza 1
kod ROM
Faza 2
Secondary program loader (SPL)
Faza 3
Tertiary program loader (TPL)
Koniec
Jadro
˛
OS w pamieci
˛
55/67
Sekwenca rozruchowa. Faza 1: kod ROM
I kod ROM - uruchamiany po
właczeniu
˛
zasilania;
I zapisany w SoC (system on a chip)
podczas produkcji
I kod ROM potrafi zaadresować mała˛
przestrzeń SRAM dostepnej
˛
w SoC
(4kB - kilkaset kB)
56/67
Sekwenca rozruchowa. Faza 1: kod ROM
Kod ROM ładuje niewielki program rozruchowy do SRAM. Odczytuje
go z:
I
pierwszych stron pamieci
˛ NAND flash,
I
pamieci
˛ flash dołaczonej
˛
przez SPI (Serial Peripheral Interface),
I
pierwszych sektorów urzadzenia
˛
MMC (karty SD),
I
strumienia bajtów z interfejsu Ethernet, USB lub UART;
57/67
Sekwenca rozruchowa. Faza 2: SPL
I Secondary program loader (SPL).
I SPL uruchamia m.in. kontroler
pamieci
˛ by móc załadować kolejna˛
cz˛eść programu rozruchowego
(TPL) do pamieci
˛ DRAM
I SPL czyta program z urzadze
˛
ń jak
kod ROM (z odpowiednim
przesunieciem
˛
adresu) lub z pliku,
np. u-boot.bin.
I SPL zwykle nie pozwala na żadna˛
interakcje˛ z użytkownikiem, ale
drukuje w konsoli informacje˛ o
wersji i postepie
˛
58/67
Sekwenca rozruchowa. Faza 3: TPL
I Pełny program rozruchowy (np.
U-Boot lub Barebox).
I Prosta linia poleceń użytkownika -
polecenia typu załaduj nowy obraz
jadra
˛
do pamieci
˛
I Efektem działania TPL jest jadro
˛
OS
w pamieci
˛
I W systemach wbudowanych
programy rozruchowe sa˛ usuwane z
pamieci
˛ po uruchomieniu jadra
˛
OS
59/67
Rozruch z programem układowym UEFI (UEFI
firmware)
UEFI - Universal Extensible Firmware Interface (UEFI) standard
(http://www.uefi.org)
Faza 1
Procesor ładuje UEFI boot manager firmware z
pamieci
˛ flash. Możliwa interakcja z użytkownikiem przez interfejs tekstowy lub graficzny
Faza 2
Boot manager ładuje boot firmware z EFI System
Partition (ESP) lub dysku twardego/SSD (lub z serwera
sieciowego przez PXE). Format partycji to FAT32.
Faza 3
Bootloader ładuje jadro
˛
OS do pamieci
˛
60/67
Rozruch z UEFI
I
TPL powinien znajdować sie˛ w pliku:
< e f i _ s y s t e m _ p a r t i t i o n > / boot / boot <machine_type_short_name > . e f i
I
Na przykład dla maszyny x86_64:
/ e f i / boot / bootx64 . e f i
61/67
Rozruch z UEFI
Programy TPL:
I
GRUB 2
I
I
I
I
GNU Grand Unified Bootloader, wersja 2,
Najcz˛eściej stosowany z OS Linux na platformach PC
https://www.gnu.org/software/grub/.
gummiboot
I
I
I
Zintegorwany z systemd (menadżer systemu i usług)
Licencja LGPL v2.1
https://wiki.archlinux.org/index.php/Systemd-boot.
62/67
Programy rozruchowe
Nazwa
Das U-Boot
Barebox
GRUB 2
RedBoot
CFE
YAMON
Architektura
ARM, Blackfin, MIPS, PowerPC, SH
ARM, Blackfin, MIPS, PowerPC
X86, X86_64
ARM, MIPS, PowerPC, SH
Broadcom MIPS
MIPS
63/67
Od programu rozruchowego do jadra
˛
OS
Informacje przekazywane przez program rozruchowy do jadra
˛
OS:
I
Podstawowe informacje o wykrytym sprz˛ecie (rozmiar fizycznej
RAM, szybkość zegara CPU)
I
Architektury PowerPC i ARM - unikatowy numer rodzaju SoC
I
[Opcjonalnie] lokalizacja i rozmiar binarnego drzewa urzadze
˛
ń
(device tree binary, dtb)
I
[Opcjonalnie] lokalizacja i rozmiar minimalnego systemu plików
(initial RAM disk)
64/67
Drzewo urzadze
˛
ń
Drzewo urzadze
˛
ń (device tree) - definiuje sprz˛et systemu
komputerowego
I
plik z rozszerzeniem .dts
I
zwykle przekazywane do jadra
˛
OS przez program rozruchowy,
może też być “przyklejone” do jadra
˛
na stałe
I
Format - OpenBoot (Sun Microsystems) sformalizowany jako
specyfikacja Open Firmware, IEEE standard IEEE1275-1994
(maszyny PowerPC, potem ARM i inne).
http://devicetree.org
65/67
Po uruchomieniu jadra
˛
...
I
Jadro
˛
szuka głównego systemu plików, którym może być:
I
I
I
initramfs
obraz systemu plików podany jako root= w linii poleceń jadra
˛
Jadro
˛
wykonuje program, którym domyślnie jest:
I
I
/init dla initramfs,
/sbin/init dla zwykłego systemu plików
I
Program init uruchamiany jest z uprawnieniami root-a.
I
Jest to pierwszy proces w systemie operacyjnym, wiec
˛ otrzymuje
PID 1
I
Jeśli init nie może zostać uruchomiony, wystapi
˛ “kernel panic”
I
Po procesie init dziedzicza˛ wszystkie inne procesy w systemie
66/67
Zadania programu-demona init
Init zarzadza
˛
cyklem życia OS, od uruchomienia do zamkniecia:
˛
I
Podczas rozruchu systemu - uruchamia programy-demony i
konfiguruje parametry systemu
I
[opcjonalnie] uruchamia program-demon getty w terminalach,
który umożliwia logowanie
I
Adoptuje osierocone procesy (w wyniku nagłego zamkniecia
˛
procesu-rodzica i braku innych procesów w grupie watków)
˛
I
Odpowiada na nagłe zamkniecie
˛
procesów-dzieci poprzez
przechwycenie sygnału SIGCHLD (zapobieganie tworzeniu
procesów-zombie)
I
Uruchamia ponownie programy-demony
I
Obsługuje proces zamykania OS
67/67

Podobne dokumenty