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