Linux Kernel Podróż do wnętrza systemu cz 1

background image

Jądro Linuksa

Linux Kernel (1/7): Wprowadzenie, kompilacja i instalacja

28

listopad 2009

Jądro Linuksa

Linux Kernel (1/7): Wprowadzenie, kompilacja i instalacja

29

www.lpmagazine.org

lin

ux

@

so

ftw

ar

e.

co

m

.p

l

Linux Kernel: Podróż

do wnętrza systemu

Część pierwsza (1/7): Wprowadzenie, kompilacja i instalacja

Wszyscy wiemy, że jądro jest podstawową częścią systemu operacyjnego, odpowiedzialną za tak
newralgiczne zadania jak zarządzanie zasobami sprzętowymi oraz izolację procesów. Wszystkie
najpopularniejsze dystrybucje systemu Linux dostarczane są w postaci gotowej całości – programów
skompilowanych i skonfigurowanych tak, aby działały bezproblemowo na możliwie jak największej
liczbie komputerów. To właśnie uniwersalność i łatwość konfiguracji przyczyniły się do eksplozji
zainteresowania systemami linuksowymi w ostatnich latach. Czy jednak naprawdę musimy decydować
się na gotowe, ale w dużym stopniu nieoptymalne dla naszych potrzeb rozwiązania?

Rafał Kułaga

D

awno, dawno temu, kiedy nie było jesz-
cze dystrybucji systemu Linux w formie,
do jakiej przywykliśmy obecnie, cały sys-
tem należało budować od podstaw. Powo-

dowało to bardzo wiele problemów, głównie ze względu
na ogromną wiedzę, jaką należało posiąść przed rozpoczę-
ciem budowy systemu dla określonego komputera. Wyni-
ki były jednak świetne – systemy tworzone według takiej
filozofii były doskonale dopasowane do danego kompute-
ra, nie tylko poprzez odpowiedni wybór oprogramowania,
lecz również sztuczki stosowane na etapie kompilacji. Ta-
kie podejście do dziś ma wielu zwolenników, szczególnie
wśród starszych użytkowników systemów opartych na ją-
drze Linux, ogranicza jednak dostępność systemu dla po-
czątkujących.

W celu rozwiązania wymienionych problemów, po-

wstały dystrybucje systemu Linux. Ich wykorzystanie za-
wsze jest kompromisem pomiędzy wydajnością, a wygo-
dą obsługi. Pomimo faktu, iż niektóre dystrybucje pozwa-
lają na budowę pakietów ze źródeł w trakcie instalacji (np.
Gentoo), większość korzysta z tzw. pakietów binarnych
– zawierających oprogramowanie w formie gotowej do

uruchomienia. Takie rozwiązanie ogranicza oczywiście
liczbę architektur sprzętowych, na których może zostać
uruchomiona dana wersja dystrybucji, pozwala jednak
na dotarcie do szerokiej grupy odbiorców. Dla przeciętne-
go użytkownika, przyzwyczajonego do systemów z rodzi-
ny Microsoft Windows, przesiadka na dowolną dystrybu-
cję byłaby z pewnością nieznośna, gdyby nie dostępność
oprogramowania w postaci binarnej.

Dlaczego wspominam o tych zagadnieniach we wstę-

pie pilotażowego artykułu cyklu o budowie, konfiguracji i
programowaniu jądra Linux? Otóż dlatego, iż odpowied-
nia konfiguracja jądra systemu może przyczynić się do
znacznego wzrostu wydajności oraz bezpieczeństwa sys-
temu. Jeżeli nie dokonałeś rekompilacji jądra systemu, to
z bardzo dużym prawdopodobieństwem jest ono nieopty-
malne dla Twoich potrzeb.

Jądro rezyduje w pamięci przez cały czas, gdy uru-

chomiony jest system operacyjny. To ono decyduje o tym,
przez jak długi okres czasu (zwany kwantem czasu) pro-
ces wykonywany jest przez procesor. Jeżeli jądro napisa-
ne byłoby w sposób nieoptymalny, to w znacznym stopniu
odbiłoby się to na wydajności całego systemu.

background image

Jądro Linuksa

Linux Kernel (1/7): Wprowadzenie, kompilacja i instalacja

28

listopad 2009

Jądro Linuksa

Linux Kernel (1/7): Wprowadzenie, kompilacja i instalacja

29

www.lpmagazine.org

Aby w pełni zrozumieć zasadę działania

jądra systemu oraz poszczególnych jego me-
chanizmów, konieczne jest zapoznanie się z
podstawowymi paradygmatami związanymi
z budową tej części systemu. W tym cyklu ar-
tykułów zostaną poruszone zagadnienia takie
jak: rekompilacja jądra, proces uruchamiania
systemu, zarządzanie procesami oraz zasoba-
mi, obsługa systemów plików, mechanizmy
sieciowe systemu Linux, mechanizmy zabez-
pieczeń na poziomie jądra (SELinux), tworze-
nie modułów jądra oraz pisanie prostych ste-
rowników urządzeń.

Nie szkodzi, jeżeli wcześniej nie miałeś

styczności z tymi zagadnieniami – wszyst-
ko zostanie przejrzyście omówione na przy-
kładach. Aby jednak w pełni skorzystać z in-
formacji zawartych w tym cyklu, powinie-
neś opanować język C przynajmniej w stop-
niu podstawowym – jest to bowiem język
programowania w którym zostało napisa-
ne jądro.

W tej części cyklu zajmiemy się pod-

stawami budowy jądra systemu operacyjne-
go. Podstawowym tematem tego artykułu jest
jednak wybór odpowiedniej wersji jądra Li-
nux, jego kompilacja oraz wykorzystanie w
systemie. Zapraszam do lektury!

Jądro systemu

Zanim przejdziemy do dalszej części artykułu,
w której zajmiemy się praktycznymi aspekta-
mi konfiguracji jądra Linux, warto zastanowić
się nad budową tej części systemu oraz jego
miejscem w architekturze nowoczesnego sys-
temu operacyjnego.

Zadania jądra

We współczesnym modelu warstwowej bu-
dowy systemu komputerowego, jądro syste-
mu odpowiada za zapewnienie środowiska
dla aplikacji uruchamianych przez użytkow-
nika. We współczesnych systemach ope-
racyjnych działa jednocześnie wiele róż-
nych aplikacji, a jak wiemy, procesor mo-
że jednocześnie wykonywać tylko jeden
program (pomijam tu procesory wielordze-
niowe lub systemy wieloprocesorowe). Pro-
blemem jest również zapewnienie izolowa-
nego środowiska działania dla każdego pro-
cesu – niemożliwe jest bowiem wykorzysta-
nie jednej przestrzeni adresowej przez wie-
le programów. Konieczne jest także zdefi-
niowanie mechanizmów obsługi urządzeń
wejścia/wyjścia oraz zapewnienie możli-
wości komunikacji międzyprocesowej, oraz
wywołań systemowych, wykorzystywanych
w celu komunikacji procesów z jądrem (Ry-
sunek 1).

W celu zapewnienia możliwości jedno-

czesnego wykonywania wielu procesów, wy-
korzystywana jest część jądra zwana schedu-
lerem
, odpowiadająca za określanie, który
proces ma mieć w danej chwili dostęp do pro-
cesora oraz czasu tego dostępu (zwany kwan-
tem). Po upłynięciu kwantu, lub zaistnieniu
innego zdarzenia powodującego koniecz-
ność przerwania wykonywania danego pro-
cesu, dokonywane jest wywłaszczenie zada-
nia. Wskutek wywłaszczenia, następne zada-
nie (określane przez algorytm kolejkowania)
uzyskuje dostęp do procesora. Jądro systemu
pozwalające na jednoczesne działanie wielu
procesów, nazywamy wielozadaniowym.

Każdy z uruchamianych programów

wymaga do poprawnego działania wła-
snej przestrzeni adresowej. Przy wywoła-
niu programu, jądro alokuje niezbędną pa-
mięć (m. in. stos) oraz wykonuje skok pod
adres określający początek kodu aplikacji.
Każdy z procesów działa w podobny spo-
sób, w jaki byłby wykonywany gdyby był
jedynym zadaniem wykonywanym przez
procesor – wszelkie funkcje związane z za-
pewnieniem ochrony obszarów wykorzysty-
wanych przez inne aplikacje przejmuje ją-
dro systemu. Stosowane w tym celu tech-
niki nazywane są pamięcią wirtualną – po-
zwalają bowiem na nadawanie obszarom pa-
mięci fizycznej dowolnie określonych ad-
resów, które następnie wykorzystywane są
przez procesy. Funkcje te wymagają wspar-
cia ze strony procesora, a konkretnie jego
części zwanej MMU (ang. Memory Mana-
gement Unit
).

W trakcie wykonywania programów, bar-

dzo często okazuje się, że ilość pamięci RAM
naszego komputera jest niewystarczająca do
przechowywania wszystkich niezbędnych da-
nych. W takiej sytuacji, nowoczesne jądra sys-
temu zapisują określone fragmenty pamięci
na urządzeniach pamięci masowej, takich jak
dyski twarde. Gdy zaistnieje potrzeba odwoła-
nia się do danych znajdujących się na partycji
wymiany (ang. swap partition), jądro wczytu-
je określony obszar do pamięci operacyjnej.
Technika ta pozwala na wydajniejszą obsługę
dużych aplikacji.

W celu skutecznego wykonywania swo-

ich funkcji, jądro musi zostać odizolowane
od wykonywanych aplikacji. Umożliwia to
zastosowanie podziału na przestrzeń użyt-
kownika (ang. userspace) oraz jądra (ang.
kernelspace). Procesy działające w przestrze-
ni użytkownika nie mają dostępu do danych
znajdujących się w przestrzeni jądra. Wsku-
tek tego, dane jądra nie są narażone na mo-
dyfikację przez niepowołane procesy. Zwróć

uwagę, że taka ingerencja w zawartość pa-
mięci zawierającej kod jądra mogłaby stano-
wić ogromne zagrożenie dla bezpieczeństwa
systemu – pamiętajmy, że to jądro decyduje,
czy dany użytkownik uprawniony jest do do-
stępu do danego pliku, wywołania systemo-
wego itp.

Skoro procesy nie mają dostępu do prze-

strzeni jądra, to w jaki sposób odbywa się ich
komunikacja z jądrem? Pamiętamy przecież,
że każdy z procesów działa w osobnej, wir-
tualnej przestrzeni adresowej. W celu zapew-
nienia możliwości komunikacji międzypro-
cesowej wykorzystywane są rozmaite techni-
ki, takie jak deskryptory plików, sygnały, se-
mafory, gniazda oraz kolejki wiadomości. Ich
działanie polega na wykorzystaniu funkcji za-
pewnianych przez jądro systemu. Wywołanie
większości z nich odbywa się przy użyciu tzw.
wywołań systemowych (ang. system calls, po-
tocznie syscalls).

W obrębie jądra systemu (lub jako tzw.

moduły) funkcjonują sterowniki urządzeń.
Ich działanie opiera się na zapewnieniu war-
stwy abstrakcji dla funkcji realizowanych
w ścisłej zależności od wykorzystywanego
sprzętu. Dzięki temu, programista nie musi
znać szczegółów działania sprzętu, lecz jedy-

Rysunek 1.

Budowa systemu operacyjnego z ją-

drem monolitycznym

���������������������

�����������������

����������������������������

���

������

�����������

���

Rysunek 2.

Budowa systemu operacyjnego korzy-

stającego z mikrojądra

�������

����������

�����������

��������������������������

background image

30

listopad 2009

Jądro Linuksa

Linux Kernel (1/7): Wprowadzenie, kompilacja i instalacja

31

www.lpmagazine.org

Jądro Linuksa

Linux Kernel (1/7): Wprowadzenie, kompilacja i instalacja

nie zestawy wywołań, służących do obsługi
mechanizmów abstrakcji.

Przestrzeń jądra

a przestrzeń użytkownika

Jak już powiedzieliśmy, w większości syste-
mów operacyjnych istnieje wyraźny podział

na przestrzeń jądra oraz przestrzeń użytkow-
nika. Większość z Czytelników z pewnością
miała do czynienia z tworzeniem aplika-
cji działających w przestrzeni użytkowni-
ka. Cykl ten ze względu na naturę tematyki
będzie zajmował się głównie zagadnienia-
mi związanymi z przestrzenią jądra. Czym

więc, w dużym skrócie, charakteryzuje się
programowanie w przestrzeni jądra?

Będąc w przestrzeni jądra, mamy pełen

dostęp do wszystkich zasobów systemu. Wy-
nikają z tego nie tylko bardzo duże możliwo-
ści, lecz również odpowiedzialność – musi-
my mieć świadomość, że każdy z błędów mo-
że spowodować zawieszenie systemu, lub,
co gorsza, narażenie przechowywanych da-
nych. Z tego względu, w zagadnieniach zwią-
zanych z realizacją funkcji charakterystycz-
nych dla jądra, istnieje tendencja do przeno-
szenia ich do przestrzeni użytkownika, gdzie
mogłyby być realizowane przez wyspecjalizo-
wane serwery.

Następną różnicą, której bardzo często nie

uświadamiają sobie początkujący programiści,
jest to, iż moduły jądra (oraz jego część głów-
na, nazywana statyczną) nie mają dostępu do
funkcji biblioteki standardowej C. W modu-
le jądra nie możemy więc wywołać np. funk-
cji

printf()

, ponieważ kod ten nie jest linko-

wany z biblioteką standardową (cechę tę okre-
śla się jako samodzielność). Większość funk-
cji posiada jednak odpowiedniki, które może-
my wykorzystać w tworzonych przez nas mo-
dułach jądra, np. dla funkcji

printf()

jest nim

kprintf()

.

Oczywiście istnieje jeszcze wiele innych

różnic, które omówimy w następnych czę-
ściach cyklu, a w szczególności w części do-
tyczącej tworzenia modułów jądra.

Rodzaje jądra systemu

Istnieje wiele metodologii budowy jądra sys-
temu operacyjnego. Głównym parametrem,
pod względem którego dokonywany jest po-
dział na poszczególne kategorie, jest rozdzie-
lenie zadań jądra pomiędzy serwery działają-
ce w przestrzeni użytkownika oraz część ją-
dra rezydującą w przestrzeni jądra. Nie moż-
na jednoznacznie orzec, która z tych meto-
dologii jest najlepsza – każda ma swoje za-
lety i wady oraz znajduje zastosowania w in-
nej klasie systemów operacyjnych (np. syste-
mów dla urządzeń wbudowanych).

Najważniejsze z istniejących obecnie filo-

zofii budowy jądra systemu to:

• Jądro monolityczne;
• Mikrojądro;
• Jądro hybrydowe;
• Nanokernel i exokernel.

Przyjrzyjmy się krótko każdemu z tych typów.

Jądro monolityczne

Koncepcja jądra monolitycznego (ang. mo-
nolithic kernel
) polega na budowie jądra ja-

Rysunek 3.

Schemat numeracji wersji jądra Linux serii 2.6

������

������

����������

����������

����������

����������

����������

����������

��������

��������

��������

��������

Rysunek 4.

Strona główna kernel.org

background image

30

listopad 2009

Jądro Linuksa

Linux Kernel (1/7): Wprowadzenie, kompilacja i instalacja

31

www.lpmagazine.org

Jądro Linuksa

Linux Kernel (1/7): Wprowadzenie, kompilacja i instalacja

ko jednolitego, dużego programu działają-
cego w przestrzeni jądra (Rysunek 1). Kla-
syczne jądro monolityczne zajmuje się obsłu-
gą wszystkich funkcji jądra systemu, jednak
większość wykorzystywanych obecnie ją-
der, budowanych w oparciu o tą metodolo-
gię posiada możliwość dynamicznego dołą-
czania modułów, gdy nastąpi taka potrzeba
(np. po podłączeniu do komputera urządze-
nia pamięci masowej USB). Przykładem ją-
dra monolitycznego jest Linux oraz jądra sys-
temów UNIX.

Największą zaletą jądra monolitycznego

jest jego wysoka wydajność, wynikająca z za-
stosowania jednej, spójnej przestrzeni adreso-
wej, w której działa większość mechanizmów
jądra. Dzięki temu, nie jest konieczne przełą-
czanie kontekstów procesów przy wykonywa-
niu podstawowych funkcji systemu, tak jak ma
to miejsce w mikrojądrach, wykorzystujących
dużą liczbę serwerów przestrzeni użytkowni-
ka. Znacznie ułatwiona zostaje również komu-
nikacja pomiędzy poszczególnymi elementa-
mi jądra.

Główna wada jądra monolitycznego wy-

nika z tej samej cechy, która jest źródłem
wszystkich jego zalet, a mianowicie – zasto-
sowania jednorodnej przestrzeni adresowej.
Podejście takie powoduje bowiem znacz-
ną komplikację rozwoju jądra oraz dużą po-
datność na błędy. Co więcej, wspólna prze-
strzeń adresowa oznacza, iż błąd w jednej
części jądra może spowodować awarię całe-
go systemu.

Mikrojądro

Zupełnie inne podejście do realizacji za-
dań jądra systemu reprezentuje koncepcja
mikrojądra. Opiera się ona na implemen-
tacji jedynie podstawowych i zupełnie nie-
zbędnych funkcji w programie działającym
w przestrzeni jądra. Pozostałe funkcje reali-
zowane są przy użyciu tzw. serwerów – pro-
gramów działających w przestrzeni użyt-
kownika (Rysunek 2). Przykładem mikro-
jądra jest jądro systemu BeOS, MINIX oraz
Mach i L4.

Podstawową zaletą mikrojądra jest teo-

retycznie większe bezpieczeństwo, wynika-
jące ze znacznego uproszczenia kodu dzia-
łającego w trybie jądra. Serwery działają w
przestrzeni użytkownika, przez co podlega-
ją podobnym ograniczeniom co większość
procesów. Mikrojądra doskonale nadają się
do zastosowania w systemach wbudowa-
nych, dzięki znacznie mniejszej ilości pa-
mięci zajmowanej przez programy niezbęd-
ne do wykonywania podstawowych funk-
cji systemu.

Jak już wspomnieliśmy w paragrafie do-

tyczącym jąder monolitycznych, główną wa-
dą mikrojądra jest duży wydatek oblicze-
niowy związany z przełączaniem pomiędzy
serwerami działającymi w przestrzeni użyt-
kownika. Co więcej, w rozbudowanych sys-
temach operacyjnych, przeznaczonych dla
komputerów typu desktop, mikrojądro wraz

z serwerami może zajmować znacznie więcej
pamięci niż standardowe jądro monolityczne.
Wynika to z faktu, iż każdy serwer jest osob-
nym programem, który dodatkowo może być
napisany w języku wysokiego poziomu. Pro-
blematyczne jest również zapewnienie ko-
munikacji pomiędzy procesami użytkowni-
ka a serwerami.

Rysunek 5.

Program konfiguracyjny jądra działający w trybie tekstowym

Rysunek 6.

Program konfiguracyjny jądra działający w trybie tekstowym

background image

32

listopad 2009

Jądro Linuksa

Linux Kernel (1/7): Wprowadzenie, kompilacja i instalacja

33

www.lpmagazine.org

Jądro Linuksa

Linux Kernel (1/7): Wprowadzenie, kompilacja i instalacja

Jądro hybrydowe

Jądra posiadające zarówno cechy mikroją-
dra jak i jądra monolitycznego, nazywamy
hybrydowymi. Podstawowe założenie pozo-
staje w ich przypadku takie samo, jak w mi-
krojądrach – znaczna część funkcji realizo-
wana jest przy pomocy serwerów działają-
cych w przestrzeni użytkownika. Jądra hy-
brydowe charakteryzuje się jednak realizacją
pewnych funkcji w programie działającym w
przestrzeni jądra, w celu zwiększenia wydaj-
ności. Przykładem jądra hybrydowego jest
jądro wykorzystywane w systemach rodziny
Microsoft Windows NT.

Nanokernel i exokernel

Wraz z rozwojem systemów operacyjnych
przeznaczonych dla urządzeń wbudowanych,
coraz większe znaczenie ma minimalizacja
wymagań sprzętowych jakie narzuca jądra.
Odpowiedzią na te potrzeby są dwa nowe typy
jądra systemu: nanokernel oraz exokernel.

Pod pojęciem nanokernela rozumiemy ją-

dro zbudowane w oparciu o założenia charak-
terystyczne dla mikrojądra, ze szczególnym
naciskiem na minimalizację objętości progra-
mu znajdującego się stale w pamięci. Nano-
kernel ma za zadanie realizować jedynie pod-
stawowe funkcje jądra, w sposób jak najbar-
dziej efektywny.

Exokernel jest nanokernelem, w którym

zadania związane z zarządzaniem zasobami
systemu zostały przekazane aplikacjom prze-
strzeni użytkownika. Zadaniem jądra jest je-
dynie zapewnienie, że procesy nie będą nad-
pisywać danych należących do innych pro-
cesów.

Jądro Linux

Po zapoznaniu się z podstawami budowy
systemów operacyjnych, nadszedł czas aby-
śmy skupili się na jądrze Linux. Nie jest to
jedynie zbiór wielu milionów linii kodu,
który na początku lat 90 umożliwił zbudo-

wanie pełnowartościowego, wolnego syste-
mu operacyjnego, ale również największy
na świecie program o otwartym kodzie źró-
dłowym. Zajmiemy się teraz krótko histo-
rią, budową oraz architekturami, na których
działa jądro Linux.

Historia Linuksa

Wszyscy wiemy, iż osobą odpowiedzialną za
rozpoczęcie prac nad jądrem Linux jest Linus
Torvalds. Za datę powstania systemu przyjmu-
je się 26 sierpnia 1991, kiedy to wysłał on na
grupę dyskusyjną wiadomość, informującą o
tworzonym amatorsko systemie operacyjnym.
Linus Torvalds z pewnością nie mógł przewi-
dzieć, że jego dzieło stanie się początkiem re-
wolucji.

Jak wiemy, system operacyjny skła-

da się ze znacznie większej ilości kompo-
nentów niż samo jądro. W celu utworzenia
kompletnego systemu operacyjnego, jądro
Linux połączono z narzędziami przestrzeni
użytkownika, zapewnianymi przez projekt
GNU, zapoczątkowany we wrześniu 1983
roku przez Richarda Stallmana. Zdaniem
części osób ze społeczności związanych z
tymi projektami, prowadzi to do konieczno-
ści określania całości jako GNU/Linux (jest
tak np. w dystrybucji Debian GNU/Linux).
Nie będziemy tu roztrząsać tego tematu, po-
nieważ nie jest on zbyt ważny z punktu wi-
dzenia cyklu artykułów. Obiektywnym fak-
tem pozostaje jednak, iż rozwój Linuksa nie
byłby możliwy bez narzędzi dostarczanych
przez projekt GNU.

Już w 1993 roku powstały pierwsze dys-

trybucje systemu Linux, pozwalające na je-
go wykorzystanie przez zwykłego użytkow-
nika – Slackware i Debian. Znamienne jest, iż
nazwa dystrybucji Slackware, obecnie uzna-
wanej za przeznaczoną dla zaawansowanych
użytkowników, oznacza w wolnym tłuma-
czeniu oprogramowanie dla leniwych. W po-
czątkach systemu Linux, za leniwych uznawa-

no bowiem tych, którzy nie budowali systemu
od podstaw.

W ostatnich latach znacznie wzrosło za-

interesowanie Linuksem wśród początkują-
cych użytkowników komputerów. Stało się
to głównie za sprawą dystrybucji takich jak
Ubuntu, które główny nacisk kładą na ła-
twość instalacji i konfiguracji. Z pewnością
jest to zjawisko bardzo korzystne dla całej
społeczności – producenci sprzętu kompute-
rowego zaczynają bowiem postrzegać Linuk-
sa na równi z systemami Microsoft Windows.
Oznacza to nie tylko zwiększoną dostępność
sterowników, lecz również znacznie lepszą
kompatybilność urządzeń z systemami spod
znaku pingwina.

Budowa jądra Linux

Jądro Linux jest typowym jądrem monolitycz-
nym. Obsługuje jednak możliwość dynamicz-
nego dołączania fragmentów kodu, w postaci
tzw. modułów.

Obecnie, jądro Linuksa składa się z pra-

wie 12 milionów linii kodu. Jest to jeden z naj-
większych i najszybciej rozwijanych progra-
mów na świecie.

Nie chcę jednak wyprzedzać treścią na-

stępnych artykułów – budową wszystkich
najważniejszych mechanizmów jądra oraz
tworzeniem modułów i prostych sterow-
ników zajmiemy się w dalszych częściach
cyklu.

Obsługiwane architektury

Systemom opartym na jądrze Linux często
zarzuca się niedopasowanie do potrzeb ty-
powego użytkownika komputera. Z opinią
tą można się zgadzać lub nie, trzeba jednak
przyznać, iż jest to niezwykle elastyczny
system, który znajduje bardzo wiele zasto-
sowań, począwszy od zabawek i systemów
wbudowanych, aż do najszybszych super-
komputerów na świecie.

Niektóre z architektur wspieranych przez

jądro Linux to: x86 (większość kompute-
rów osobistych), 64-bitowe rozwiązania Inte-
la i AMD, mikrokontrolery oparte na rdzeniu
ARM (wykorzystywanego w ogromnej ilości
systemów wbudowanych), procesory oparte
na rdzeniu MIPS (sieciowe systemy wbudo-
wane), PowerPC (wydajne procesory RISC,
przeznaczone m.in. dla systemów wbudowa-
nych), Microblaze (architektura, którą może-
my implementować w układach logiki progra-
mowalnej FPGA).

Na rynku urządzeń mobilnych widać ten-

dencję do stosowania systemów opartych na
jądrze Linux. Dotyczy to nie tylko sprzętu ta-
kiego jak netbooki, lecz również PDA i smart-

Listing 1.

Przykładowy wpis konfiguracyjny dla nowego jądra w programie rozruchowym GRUB

title Kernel 2.6.30.5 – nowy

# etykieta

root (hd0,0)

# dysk główny

kernel /boot/bzImage-2.6.30.5

root

= /dev/sda1 ro quiet

# ścieżka do

obrazu jądra i opcje

Listing 2.

Przykładowy wpis konfiguracyjny dla nowego jądra w programie rozruchowym LILO

image

=/boot/bzImage-2.6.30.5

# ścieżka do obrazu jądra

label

=Kernel 2.6.30.5 - nowy

# etykieta

read

-only

# tryb tylko do odczytu

root

=/dev/sda1

# partycja główna

background image

32

listopad 2009

Jądro Linuksa

Linux Kernel (1/7): Wprowadzenie, kompilacja i instalacja

33

www.lpmagazine.org

Jądro Linuksa

Linux Kernel (1/7): Wprowadzenie, kompilacja i instalacja

fony. Przykładem mogą być chociażby platfor-
my Android oraz Moblin.

Przygotowanie

do kompilacji jądra

Zanim zajmiemy się omówieniem procesu
pobrania i instalacji najnowszej wersji jądra,
warto zastanowić się, jakie pakiety będą nam
potrzebne do jego konfiguracji oraz kompila-
cji. Po instalacji nowego jądra, często okazu-
je się również, że do poprawnej pracy syste-
mu konieczna jest aktualizacja pakietów wy-
mienionych poniżej.

Narzędzia kompilacji

Jeżeli jesteś początkującym użytkownikiem
systemu Linux, to z pewnością masz nieprzy-
jemne wspomnienia związane z kompilacją
programów ze źródeł. Błędy, które z pewno-
ścią często napotykałeś (zwłaszcza przy okazji
budowania mniej popularnych aplikacji) wy-
nikały z używania niewłaściwej wersji pakie-
tu GCC lub błędów samego programisty. Mam
przyjemność poinformować Cię, że w przy-
padku jądra, prawie na pewno nie napotkasz
żadnych problemów – jest to bowiem kod o
znaczeniu absolutnie krytycznym, dokładnie
przeanalizowany przez najlepszych programi-
stów na świecie. W celu sprawnej kompilacji
powinieneś jednak upewnić się, że dysponu-
jesz najnowszymi wersjami kilku pakietów, a
mianowicie: kompilatora GCC, narzędzi binu-
tils
oraz programu make.

Jako że jądro Linux napisane jest w ję-

zyku C (ze wstawkami w asemblerze), bę-
dziesz potrzebował możliwie najnowszej
wersji kompilatora GCC. Jest on dostępny w
repozytoriach wszystkich dystrybucji, więc
na pewno nie będziesz miał problemów z je-
go instalacją.

Do przeprowadzenia kompilacji jądra,

będziesz również potrzebował pakietu binu-
tils
, zawierającego narzędzia służące do ope-
rowania na plikach binarnych (m. in. linker i
asembler).

Program make wykorzystywany jest w

procesie automatycznej kompilacji i linkowa-
nia programów składających się z wielu pli-
ków źródłowych.

Programy zależne od jądra

Większość programów działających w prze-
strzeni użytkownika jest niezależna od uży-
wanej wersji jądra systemu. Istnieje jed-
nak pewna grupa aplikacji, które w znacz-
nym stopniu zależne są od działania pew-
nych mechanizmów jądra. Instalacja nowe-
go jądra może spowodować, że programy
te zaczną działać niepoprawnie lub w ogó-

le nie dadzą się uruchomić. Jeżeli po rekom-
pilacji jądra zauważyłeś problemy, powinie-
neś zainstalować nowsze wersje odpowied-
nich programów.

Część programów, które mogą wyma-

gać uaktualnienia po instalacji nowego ją-
dra, to:

module-init-tools – narzędzia służące do

obsługi modułów jądra;

udev – narzędzia służące do dynamiczne-

go tworzenia plików urządzeń w katalogu
/dev;

util-linux – zbiór podstawowych narzę-

dzi wykorzystywanych w systemach
Linux;

• Narzędzia do obsługi systemów plików.

Pobranie najnowszej wersji jądra

Najnowsza wersja jądra Linux jest zawsze do-
stępna na stronie http://www.kernel.org/. Znaj-
dują się tam nie tylko pełne wersje źródeł, lecz
również tzw. patche – pliki umożliwiające ak-
tualizację posiadanych źródeł jądra. Więcej o
ich wykorzystaniu powiemy w następnej czę-
ści cyklu, kiedy zajmiemy się optymalizacją
konfiguracji jądra.

Po otworzeniu strony ze źródłami jądra

Linux, z pewnością zauważysz, że dostęp-
nych jest wiele różnych wersji, z których część
oznaczona jest jako stabilna, część jako wersje
testowe. Którą powinieneś wybrać?

Oznaczenia wersji jądra

W większości przypadków, najodpowiedniej-
szym rozwiązaniem będzie pobranie najnow-
szej stabilnej wersji jądra. Warto jednak po-
znać system oznaczeń wersji, aby mieć świa-
domość, w jaki sposób odbywa się rozwój tej
części systemu.

Jeżeli używałeś Linuksa jeszcze w cza-

sach jądra z rodziny 2.4, to z pewnością pa-
miętasz podział na dwie gałęzie: gałąź roz-
wojową (development) oraz stabilną (sta-
ble
). Wersje testowe oznaczane były za po-
mocą liczby nieparzystej (np. 2.5.22), zaś
stabilne przy pomocy liczby parzystej (np.
2.4.22). Taki system oznaczeń powodował
jednak wiele niedogodności oraz był nie-
zbyt zrozumiały dla początkujących użyt-
kowników.

Wraz z wprowadzeniem jądra w wer-

sji 2.6 zdecydowano się zmienić sys-
tem numerowania wersji. Zrezygnowa-
no z utworzenia osobnej gałęzi dla wer-
sji rozwojowych, decydując się na wyko-
rzystanie schematu numeracji z wersjami
-rc (ang. release candidate). Nowy sche-
mat łatwo wytłumaczyć na przykładzie

(Rysunek 3). Załóżmy, że ukazuje się wer-
sja 2.6.30 jądra. W trakcie prac, dewelo-
perzy odnajdują błędy, które zostają usu-
nięte w kolejnych wersjach stabilnych ją-
dra, oznaczanych jako 2.6.30.1, 2.6.30.2
itd. W tym samym czasie, trwają intensyw-
ne prace nad nowymi funkcjami, wskutek
czego powstają wersje testowe, oznaczane
2.6.31-rc1, 2.6-31-rc2 itd. Po kilku miesią-
cach, wersja 2.6.31-rcX zostaje uznana za
stabilną i cykl powtarza się.

Pobranie i rozpakowanie jądra

Zdecydowanie polecam Ci pobranie najnow-
szej dostępnej wersji stabilnej jądra. Mo-
żesz tego dokonać wchodząc na stronę http:
//www.kernel.org/
i klikając w link Full Source
znajdujący się obok najnowszej wersji ozna-
czonej jako stable (Rysunek 4). Źródła jądra
zajmują około 55 MB.

Jeżeli chcesz pobrać źródła w trybie tek-

stowym, to możesz tego dokonać za pomo-
cą polecenia:

wget http://kernel.org/pub/linux/
kernel/v2.6/linux-2.6.x.x.tar.gz

Aby wyświetlić informacje o najnowszych
wersjach jądra, możesz skorzystać z poleceń:

wget http://kernel.org/kdist/finger_
banner
cat finger_banner

Po pobraniu, źródła możesz rozpakować przy
użyciu polecenia:

tar -xzvf linux-2.6.x.x.tar.gz ~/
linux-src/

Zapoznamy się teraz ze strukturą katalogów ze
źródłami jądra Linux.

Struktura katalogów ze źródłami

Po rozpakowaniu archiwum ze źródłami, z
pewnością zauważysz, iż zajmują one łącznie
ponad 300 MB. Taka ilość kodu może przy-
tłaczać, w znakomitej większości są to jednak
komponenty, których nie będziesz wykorzy-
stywał w swoim systemie. Przyjrzyjmy się te-
raz zawartości najistotniejszych katalogów w
drzewie jądra:

arch – pliki zawierające implementacje

funkcji charakterystycznych dla konkret-
nych architektur sprzętowych obsługiwa-
nych przez jądro;

crypto – pliki zawierające implementacje

mechanizmów kryptograficznych jądra;

background image

34

listopad 2009

Jądro Linuksa

Linux Kernel (1/7): Wprowadzenie, kompilacja i instalacja

35

www.lpmagazine.org

Jądro Linuksa

Linux Kernel (1/7): Wprowadzenie, kompilacja i instalacja

drivers – pliki z kodem źródłowym ste-

rowników urządzeń;

firmware – pliki z kodem źródłowym ob-

sługi firmware urządzeń;

fs – pliki zawierające implementacje sys-

temów plików;

init – pliki zawierające implementacje

funkcji niezbędnych do rozruchu systemu;

ipc – pliki zawierające implementację me-

chanizmów komunikacji międzyproceso-
wej (semafory, kolejki wiadomości itp.);

kernel – pliki zawierające implementację

najważniejszych funkcji jądra (obsługa
przerwań, schedulera itp.);

mm – pliki zawierające implementację

mechanizmów związanych z zarządza-
niem pamięcią;

net – pliki zawierające implementację

mechanizmów sieciowych jądra;

security – pliki zawierające implementa-

cję mechanizmów zabezpieczeń jądra;

sound – pliki zawierające implementację

mechanizmów obsługi dźwięku;

virt – pliki zawierające implementację

mechanizmów obsługi wirtualizacji.

W głównym katalogu źródeł jądra znajdują się
również katalogi Documentation (dokumenta-
cja jądra), include (pliki nagłówkowe jądra),
oraz lib (implementacja funkcji bibliotecz-
nych jądra).

Konfiguracja jądra

Przed rozpoczęciem kompilacji powinieneś
wybrać komponenty, które chcesz zbudować
jako część statyczną jądra oraz moduły. Archi-
wum ze źródłami jądra, które przed chwilą po-
brałeś z internetu, zawiera również wygodne
narzędzia, pozwalające na szybką modyfika-
cję konfiguracji.

Konfigurację jądra możemy przeprowa-

dzić na trzy sposoby:

Odpowiadając na pytania odnośnie każ-

dego składnika jądra – szczerze odra-
dzam Ci zastosowanie tej metody, przy-
najmniej na początku. Proces ten jest bo-
wiem niezwykle czasochłonny (należy
odpowiedzieć na ponad 2000 pytań) oraz
wymaga dużej wiedzy na temat poszcze-
gólnych elementów jądra;

Korzystając z narzędzia działającego

w trybie tekstowym – w takim przy-

padku zaczynamy pracę od wczytania
standardowej konfiguracji oraz urucho-
mienia narzędzia menuconfig (Rysunek
5). Jest to zdecydowanie najlepsze roz-
wiązanie, gdy budujemy jądro na zdal-
nym systemie, np. przy użyciu połą-
czenia SSH. Należy pamiętać, iż w ce-
lu kompilacji i uruchomienia programu
menuconfig potrzebna jest biblioteka
ncurses;

Korzystając z narzędzia działającego w

trybie graficznym – podobnie jak w przy-
padku programu menuconfig, zaczynamy
od wczytania konfiguracji domyślnej, a
następnie wprowadzamy w niej zmia-
ny przy użyciu narzędzia działającego w
trybie graficznym (Rysunek 6). Mamy do
wyboru dwa programy: jeden z nich ko-
rzysta z biblioteki QT3 (xconfig), drugi z
GTK+ (gconfig).

W tym artykule omówimy dwa ostatnie z wy-
mienionych sposobów konfiguracji.

Część statyczna a moduły

Większość elementów jądra możemy zbudo-
wać jako składnik części statycznej lub jako
moduł. Jaka jest różnica pomiędzy tymi dwo-
ma rozwiązaniami i czym powinniśmy kiero-
wać się przy podjęciu decyzji?

Moduł jest skompilowanym elementem

jądra, który możemy wczytać w dowolnym
momencie po uruchomieniu systemu ope-
racyjnego (za pomocą programu modpro-
be). Gdy zdecydujemy, że wczytany do pa-
mięci moduł jest nam już niepotrzebny, mo-
żemy go usunąć. Moduły w systemie Linux
przechowywane są zazwyczaj w katalogu
/lib/modules jako pliki obiektowe z rozsze-
rzeniem .ko. Listę obecnych w systemie mo-
dułów, wraz z podstawowymi informacjami
na ich temat, możesz uzyskać przy pomocy
polecenia

lsmod

.

Część statyczna jądra (ang. base ker-

nel) to część jądra, która jest zawsze obec-
na w pamięci – nie możemy jej odłączyć.
Co więcej, dokonanie jakichkolwiek zmian
w jej obrębie wymaga ponownego urucho-
mienia systemu, a często nawet rekompila-
cji całego jądra. W części statycznej znaj-
duje się zdecydowana większość kodu, od-
powiadającego za realizację podstawowych
funkcji systemu.

Wybór składników

Po zapoznaniu się w podanymi informacja-
mi, możesz przejść do konfiguracji jądra.
Zastosujemy tu wygodną metodę, polega-
jącą na wczytaniu konfiguracji domyślnej,
a następnie wprowadzeniu modyfikacji w
obrębie interesujących nas funkcji. Pamię-
taj, aby wykonywać te czynności przy uży-
ciu konta użytkownika bez uprawnień admi-
nistratora – w przeszłości zdarzały się bo-
wiem błędy, które powodowały uszkodze-
nie ważnych plików systemowych w trakcie
kompilacji jądra.

Aby wczytać domyślną konfigurację ją-

dra, przejdź do katalogu z źródłami i wpro-
wadź polecenie:

make defconfig

Następnie, w celu uruchomienia programu
konfiguracyjnego działającego w trybie gra-
ficznym (GTK+), wydaj polecenie:

make gconfig

Jeżeli wolisz skorzystać z narzędzia wykorzy-
stującego bibliotekę QT3, możesz wydać po-
lecenie:

make xconfig

Po chwili, w czasie której narzędzie konfigura-
cyjne jest kompilowane, Twoim oczom ukaże
się program, w którym będziesz mógł zmienić
ustawienia jądra.

Opcje konfiguracyjne zostały podzielone

na następujące kategorie:

General setup – kategoria zawierająca

podstawowe opcje konfiguracyjne ją-
dra;

Processor type and features – kategoria

zawierająca opcje konfiguracyjne wpły-
wające na obsługę procesora. Niektó-
re ze znajdujących się tu opcji dotyczą
wsparcia konkretnych technologii (np.
SMP) lub aktualizacji mikrokodu pro-
cesora;

Power management and ACPI options

– kategoria zawierająca opcje konfigura-
cyjne dotyczące funkcji zarządzania ener-
gią oraz ustawienia systemu ACPI;

Bus options (PCI etc.) – kategoria zawie-

rająca opcje konfiguracyjne obsługi magi-
strali, takich jak PCI, PCI-E;

Executable file formats/Emulations – ka-

tegoria pozwalająca na wybór obsługiwa-
nych przez jądro typów plików wykony-
walnych;

• Strona główna jądra Linux – http://www.kernel.org/
• Strona KernelTrap – http://kerneltrap.org/

W Sieci

background image

34

listopad 2009

Jądro Linuksa

Linux Kernel (1/7): Wprowadzenie, kompilacja i instalacja

35

www.lpmagazine.org

Jądro Linuksa

Linux Kernel (1/7): Wprowadzenie, kompilacja i instalacja

Networking support – kategoria zawiera-

jąca opcje konfiguracyjne związane z pra-
cą różnego rodzaju urządzeń sieciowych
oraz stosu TCP/IP;

Device Drivers – kategoria umożliwiająca

wybór sterowników urządzeń, które chce-
my włączyć do części statycznej jądra lub
skompilować jako moduły;

Firmware Drivers – kategoria zawiera-

jąca opcje dotyczące obsługi firmware
urządzeń;

File Systems – kategoria umożliwia-

jąca wybór obsługiwanych systemów
plików;

Kernel hacking – kategoria zawierająca

rozmaite opcje konfiguracyjne, przydatne
przy modyfikacji kodu jądra oraz tworze-
niu własnych modułów;

Security options – kategoria zawierająca

opcje konfiguracyjne wpływające na za-
bezpieczenia wykorzystywane w syste-
mie;

Cryptographic API – kategoria zawierają-

ca opcje konfiguracyjne interfejsu krypto-
graficznego jądra systemu;

Virtualization – kategoria zawierająca

opcje związane z technologią wirtuali-
zacji;

Library routines – kategoria zawierająca

opcje konfiguracyjne funkcji bibliotecz-
nych.

Dla każdego ze składników jądra możesz wy-
brać jedną z trzech opcji: nieaktywny (N), zbu-
dowany jako moduł (M), wbudowany w część
statyczną (Y).

Po zmianie interesujących Cię opcji kon-

figuracyjnych, możesz zapisać zmiany korzy-
stając z przycisku Save.

Kompilacja jądra

Sam proces kompilacji nie powinien po-
wodować żadnych problemów – jeżeli tak
się dzieje, znaczy to, że powinieneś spraw-
dzić, czy używasz najnowszych wersji na-
rzędzi wymienionych we wcześniejszej czę-
ści artykułu.

Aby rozpocząć kompilację jądra, należy

wydać polecenie:

make

Jeżeli korzystasz z procesora wielordzenio-
wego, możesz znacznie skrócić czas kompi-
lacji, dzięki zastosowaniu opcji konfiguracyj-
nej

-jN

, gdzie

N

to liczba procesorów pomno-

żona przez 2, np.

make -j4

Po zakończeniu procesu kompilacji, możesz
przejść do następnego kroku, którym jest in-
stalacja modułów.

Instalacja modułów

Po zakończeniu procesu kompilacji jądra, na-
leży zainstalować moduły przy pomocy pole-
cenia:

make modules_install

Do jego poprawnego wykonania niezbędne są
uprawnienia użytkownika root.

Instalacja jądra

W trakcie procesu instalacji wygenerowa-
ny zostaje plik z obrazem jądra, który zosta-
je wczytany do pamięci przez program rozru-
chowy. W celu umożliwienia wyboru nowego
jądra w trakcie uruchamiania systemu, prze-
kopiujemy jego obraz do katalogu /boot oraz
odpowiednio zmodyfikujemy pliki konfigura-
cyjne boot loader'a. Opiszemy tu procedurę
dla programu rozruchowego GRUB, jednak
w przypadku LILO przebiega ona bardzo po-
dobnie (Listing 2). W razie wątpliwości, od-
wołaj się do dokumentacji wykorzystywane-
go programu.

Po zakończeniu procesu kompilacji,

obraz jądra znajduje się w pliku ~/kernel-
src/linux-2.6.x.x/arch/x86/boot/bzImage
.
Przekopiuj go do katalogu /boot za pomo-
cą polecenia:

cp ~/kernel-src/linux-2.6.x.x/arch/
x86/boot/bzImage /boot/bzImage-
2.6.x.x

Oprócz tego, konieczne jest również prze-
kopiowanie pliku ~/kernel-src/linux-2.6.x.x/
System.map
do katalogu /boot:

cp ~/kernel-src/linux-2.6.x.x/
System.map /boot/System.map-2.6.x.x

Następnym krokiem jest konfiguracja pro-
gramu rozruchowego. W przypadku pro-
gramu GRUB jest ona bardzo prosta i pole-
ga na dodaniu nowego wpisu na końcu pliku
/boot/grub/menu.lst. Przykładowy wpis został
przedstawiony na Listingu 1.

Po wykonaniu wszystkich opisanych

czynności, możesz ponownie uruchomić kom-
puter i wybrać nowe jądro w menu programu
rozruchowego.

Kernel panic?

W trakcie lektury tego cyklu z pewnością spo-
tkasz się z sytuacją, w której nowe jądro od-

mówi posłuszeństwa, wyświetlając przy star-
cie ogromne ilości komunikatów o błędach,
podsumowane krótkim napisem Kernel pa-
nic
. Nie powinieneś się tym jednak przejmo-
wać – wystarczy zresetować komputer oraz
wybrać z menu programu rozruchowego dzia-
łający obraz jądra.

Istnieje wiele przyczyn, które mogą po-

wodować powstanie błędów uniemożliwiają-
cych uruchomienie systemu z nowym jądrem.
Nie sposób wymienić tu wszystkich, jednak
jego wystąpienie zawsze świadczy o tym, że
na którymś z opisanych w artykule etapów po-
pełniłeś błąd. Bardzo często Kernel panic jest
skutkiem wadliwej konfiguracji programu roz-
ruchowego.

Podsumowanie

Tym sposobem dotarliśmy do końca pierw-
szej części cyklu. Zapoznałeś się w nim z ar-
chitekturą nowoczesnego systemu operacyj-
nego, różnymi metodologiami budowy ją-
dra oraz jego zadaniami. Omówiliśmy krót-
ko historię jądra Linux oraz jego wpływ na
rozwój ruchu Wolnego Oprogramowania,
poznaliśmy podstawowe cechy jego budo-
wy oraz architektury, na których działa. Do-
wiedziałeś się również, w jaki sposób po-
brać najnowszą wersję jądra, dokonać je-
go konfiguracji, rekompilacji oraz instala-
cji w systemie.

Jeżeli jesteś zainteresowany szczegóła-

mi związanymi z działaniem jądra systemu
operacyjnego oraz jądrem Linux, to polecam
Ci odwiedzenie stron wymienionych w tabe-
li W Sieci. Znajdziesz tam wiele informacji
na tematy, dla których zabrakło miejsca w
tym artykule.

W następnej części cyklu zajmiemy się

bliżej procesem optymalizacji jądra poprzez
wybór odpowiednich składników, odpowia-
dających naszym potrzebom. Dowiesz się
również, w jaki sposób możesz skrócić czas
uruchamiania systemu oraz zapoznasz się ze
szczegółami procesu uruchamiania systemu
Linux. Do usłyszenia!

Autor interesuje się bezpieczeństwem
systemów informatycznych, programo-
waniem, elektroniką, muzyką rockową,
architekturą mikroprocesorów oraz za-
stosowaniem Linuksa w systemach wbu-
dowanych.
Kontakt z autorem: rl.kulaga@gmail.com

O autorze


Wyszukiwarka

Podobne podstrony:
Linux Kernel podroz do wnetrza systemu
Podroze do wnetrza siebie
Podroze Do Wnetrza Siebie Fragment Pd
podroze do wnetrza siebie
podroze do wnetrza siebie
Diady komunikacyjne-podróż do wnętrza, Diady komunikacyjne
BYTOF Podróż do wnętrza umysłu, Balum Balum, PO TAMTEJ STRONIE
Podróże do wnetrza siebie
Podróż do Wnętrza Ziemi
Podroze do wnetrza siebie
nr 10 Ćwiczenie Podroz do wnętrza, kroki do wymarzonej sylwetki
SAMODOSKONALENIE, PODRÓŻE DO WNĘTRZA SIEBIE
Podróż do wnętrza Ziemi, W ஜ DZIEJE ZIEMI I ŚWIATA, ●txt RZECZY DZIWNE
Podroze do wnetrza siebie fragment
podroze do wnetrza siebie
Podroze do wnetrza siebie

więcej podobnych podstron