3. SYSTEM LINUX 3.1 Budowa jądra Linux'a Poniższy rysunek przedstawia blokow ą budow ę jądra Linux'a. The System Call Interface Process management Memory management Filesystems Device control Networking Kernel subsystems Concurrency multitasking Virtual memory Files and dirs: the VFS Ttys & device access Connectivity Features implemented Archdependent Code Memory manager File system types Block devices Character devices Network subsystem IF drivers Software Support CPU Memory Disks & CDs Consoles, etc. Features implemented as modules Nework interfaces Hardware Rys. 2.1 Schemat blokowy jądra Linux'a. [k3] LINUX Device Drivers 2 nd edition str. 5. Schemat ten przedstawia poglądow ą struktur ę budowy jądra Linux'a. Jak wida ć na diagramie, jądro podzielone jest na następujące bloki: process menagement jądro tworzy i usuwa procesy, jak również jest pośrednikiem pomiędzy urzą dzeniami I/O a procesami. Jest także pośrednikiem pomiędzy samymi procesami (np.: sygnał y, pipe). Scheduler jest managerem procesów w systemie, czyli dba o odpowiedni podzia ł czasu procesora, memory menagement modu ł ten powoduje i ż procesy widzą wirtualn ą przestrze ń adresow ą, co jest możliwe dzięki moduł owi MMU. Linux także można uruchomi ć na procesorach nie wyposaż onych w 1/6
MMU możliwe jest to dzię ki projektowi uclinux[i11]. Rożne części jądra współdziałaj ą z t ą części ą ją dra poprzez zestaw funkcji np.: malloc() / free(), filesystems Linux jest silnie zwią zany z systemem plików np. katalog /proc jest abstrakcyjnym katalogiem nie znajduje się fizycznie na żadnym noś niku. Jest to odzwierciedlenie działającego systemu w pamięci RAM. Katalog /dev jest katalogiem, którego pliki odzwierciedlają urządzenia w systemie np.: /dev/hda to pierwszy dysk podłą czony do kontrolera ATA. Linux obsługuje wiele systemów plików: fat, ntfs, vfat, ext2..., device control każde z urządze ń przyłą czonych do systemu musi mie ć swój driver [sterownik] aby funkcjonowa ć (móc si ę z nim komunikowa ć), networking system operacyjny zajmuje si ę dostarczaniem pakietów od programów do interfejsów sieciowych i na odwrót. Routing pakietów jak i rozwiązywanie nazw s ą zaimplementowane w jądrze. 3.2 Sterowniki urządze ń w systemie Linux Sterownik jest to program, który kontroluje dane urzą dzenie i dostarcza funkcji interfejsu, które umożliwiaj ą innym programom współdziałanie z danym urzą dzeniem. Sterowniki nie musz ą współdziała ć z fizycznym urządzeniem. Przykładem może być urządzenie /dev/random, które jest aktywne prawie w każ dym systemie UNIX. Urzą dzenie to dostarcza bajtów o losowych wartościach. Urządzenie to jest form ą abstrakcji i nie ma nic wspólnego ze sprzętem. Dostęp do sterowników realizowany jest za pomoc ą systemu plików. Katalog /dev to katalog, w którym znajduj ą si ę uchwyty do urządze ń. Wystarczy napisa ć ls -l /dev aby zobaczy ć jakie urządzenia mamy w systemie. Jedyn ą różnic ą jaka wyróżnia pliki urządze ń od innych plików to flaga c lub b w opisie pliku: c - oznacza urządzenie znakowe (character device), b - oznacza urządzenie blokowe (block device). Urządzenia charakteryzuj ą dwa ważne numery: major number - określa w sposób unikalny dane urzą dzenie w systemie, nie może zaistnie ć sytuacja, gdy numer ten się powtórzy, minor number - określa numer uchwytu do danego urządzenia. Pliki urządze ń tworzy si ę przez polecenie systemowe mknod: mknod "nazwa urzadzenia" "typ urzadzenia" "major number" "minor number" System Linux pracuje w dwóch trybach: uż ytkownika - jest to poziom aplikacji działają cych w systemie. 2/6
Procesy działające w tym trybie nie mog ą odwoływa ć się bezpośrednio do sprzętu, nadzorcy - jest to tak zwany kernel mode w tym trybie wykonywany jest kod jądra i moduły jądra. 3.3 Moduły jądra Modu ł jądra to fragment kodu, który może zosta ć dodany do działającego jądra Linux'a zwiększając jego funkcjonalno ść. W Linux'ie występuje kilka rodzajów modułów: character devices [urzą dzenie znakowe] minimalny zestaw funkcji dostarczany przez urzą dzenie tego typu to: open(), close(), write(), read(). Rożnica w dostępie do zwykł ego pliku i do character device jest taka, że po pliku można si ę porusza ć, a w przypadku pliku driver'a w większości przypadków dostę p jest sekwencyjny bez możliwości poruszania si ę. Przykładem może być urządzenie: /dev/ttys0 port szeregowy COM1, block devices [urzą dzenie blokowe] tak samo jak dla character devices, dostęp do tego rodzaju urządze ń nastę puje poprzez katalog /dev. W systemach UNIX dostęp do urzą dzenia blokowego możliwy jest poprzez wielokrotno ść wielkości bloku. Wielkość bloku to zazwyczaj jeden kilobajt albo inna potę ga dwójki. W tym typie urządzenia dane można pobiera ć seriami. Interfejs programisty wzbogacony jest o funkcje umożliwiają ce transfer danych blokami, network interface [interfejs sieciowy] moduł y tego typu udostępniaj ą możliwo ść przesył ania / odbierania danych poprzez interfejs sieciowy do innego host'a. Moduł y Network Interface słu żą do odbierania i wysyłania pakietów. Urzą dzenia tego typu nie maj ą odzwierciedlenia w systemie plików. Interfejsem sieciowym jest równie ż loopback [pętla zwrotna]. Rożnica w dostępie pomiędzy urzą dzeniem blokowym a urządzeniem znakowym jest taka, że dane wewnę trznie reprezentowane s ą w rożny sposób. Dla użytkownika systemu ważne jest to, że urządze ń znakowych nie instaluje si ę. Natomiast urządzenia blokowe instaluje si ę w systemie (polecenie systemowe: mount). Dysk twardy albo CDROM musimy zainstalowa ć, natomiast portu szeregowego nie musimy instalowa ć aby mie ć do niego dostęp. 3.3.1 Kompilacja modułów jądra Kompilacja modułów jądra nie jest trudniejsza niż kompilacja zwykłych aplikacji, nie musimy używa ć dziwnych narzą dzi typu DDK jak jak to jest w przypadku systemu Windows. Załóżmy, że chcemy zbudowa ć prosty modu ł o nazwie: 3/6
pierwszy_modul z pliku źródłowego: pierwszy_modul.c Aby to zrobi ć należy wyda ć następując ą komend ę: gcc D KERNEL D SMP DMODULE I/usr/src/linux/include o pierszy_modul.o c pierszy_modul.c Należy zauważy ć, że podajemy ścieżk ę z plikami nagł ówkowymi dla jądra, dla którego ten ten modu ł jest budowany: -I/usr/src/linux/include. Jest to bardzo ważne w przypadku cross-platform, poniewa ż jeś li ścieżka będzie wskazywała np. na katalog z innym jądrem ni ż ten właściwy to wystąpi ą problemy - nasz modu ł nie będzie działa ć. Użyte dyrektywy kompilatora (-D): KERNEL - informacja, że będzie to modu ł działają cy w trybie uprzywilejowanym - kernel mode, SMP - Symetric Multi Processor jeśli jądro był o kompilowane w trybie wieloprocesorowym moduły także musz ą mieć ustawion ą t ę dyrektyw ę. Jeśli jądro było kompilowane w trybie jednoprocesorowym UP (Uni Processor), to moduły powinny by ć równie ż kompilowane z taką dyrektyw ą, MODULE informacja, że program będzie kompilowany do modułu. 3.3.2 Ładowanie modułu jądra do systemu Należy pamięta ć, aby uaktywni ć w jądrze opcj ę umożliwiającą ładowanie modułów jądra. Należy to zrobi ć w głównym menu konfiguracyjnym jądra: "Loadable module support > Enable loadable module support" Aby załadowa ć modu ł jądra do systemu należy wyda ć polecenie: insmod pierwszy_modul.o Załadowane moduły można wyświetli ć poleceniem: lsmod Do usuwania modułu służy polecenie: rmmod pierwszy_modul Wyświetlenie symboli ją dra (plik widoczny jest po uaktywnieniu dynamicznego ładowania modułów jądra): cat /proc/ksyms 3.3.3 Przykładowy program najprostszy modu ł jądra Projekt z najprostszym modułem jądra znajduje si ę w katalogu kernelsimplestmodule. #include <linux/module.h> kernelsimplestmodule/kernelsimplestmodule.c #if defined(config_smp) #define SMP 4/6
#endif #include <linux/kernel.h> int init_module(void) { printk(kern_debug "Witam > Modol zainstalowany!\n"); return 0; } void cleanup_module(void) { printk(kern_debug "Zegnam > Modol zwolniony!\n"); } kernelsimplestmodule/kernelsimplestmodule.c Funkcja init_module() jest wywoływana w trakcie rejestracji moduł u w systemie czyli po wykonaniu komendy systemowej insmod. Funkcja cleanup_module() jest wywoływana w trakcie usuwania moduł u z systemu czyli po wykonaniu komendy systemowej rmmod. Modu ł kompilujemy dla platformy ARM poleceniem: kernelsimplestmodule/makefile... arm linux gcc D KERNEL I./kernel/linux 2.4.21/include DMODULE Wall O2 c o kernelsimplestmodule.o kernelsimplestmodule.c... kernelsimplestmodule/makefile Zakładamy, że pliki nagłówkowe jądra znajduj ą si ę w katalogu:./kernel/linux 2.4.21/include Zastosowano dodatkowo poziom optymalizacji: -O2. 3.3.4 Przykładowy program modu ł jądra migają cy diodami LED na płycie EP9301 Aby zademonstrowa ć jak działa bardziej realistyczny moduł jądra przyjrzyjmy si ę moduł owi short z katalogu: kernelledblinkmodule. Modu ł ten przeznaczony jest do sterowania portem równoległ ym komputera PC. Jego budowa jest na tyle elastyczna, że użyjemy go jako sterownika portów I/O, które podpięte s ą do dwóch diod świecą cych (LED) w systemie. Aby proces ładowania i zwalniania moduł ów z systemu jak najbardziej zautomatyzowa ć, utworzone zostały skrypty powłoki: make_arm.sh - kompilujący moduły dla platformy EP9301, short_load_led - automatycznie ładujący modu ł short.o do systemu, tworzy uchwyty do urządzenia poleceniem mknod. Po wykonaniu tego skryptu możemy podejrze ć poleceniem ls -la /dev, dodatkowe urządzenia, które zostały utworzone w systemie, short_blink - jest to program, który będzie komunikowa ł si ę ze sterownikiem urzą dzenia, jego zadaniem jest zapalanie i gaszenie 5/6
czerwonej lub zielonej diody LED na płycie, short_unload - automatyczne usuwanie moduł u z systemu oraz uchwytów do urządze ń. 6/6