Zajęcia 3: kompilacja jądra¶
Data: 14.03.2023
Materiały dodatkowe¶
Lektura¶
Kernel-HOWTO (niestety, przestarzałe)
Kernel-Build-HOWTO
/usr/src/linux/README
/usr/src/linux/Documentation/*
info grub
Przygotowanie źródeł jądra¶
Sklonować repozytorium gita z git.kernel.org (repozytorium linux/kernel/git/linux-stable) lub ściągniąć i rozpakować paczkę w wersji 6.7.6 z https://www.kernel.org/. W przypadku użycia gita, przejść na taga v6.7.6.
Informacje o wersjach jądra – X.Y.ZZ.ŹŹ(-abc)¶
Dawniej (wersje jądra przed 2.6)¶
Wówczas numery były postaci X.Y.ZZ(-abc).
Pierwsza liczba (X) – główny numer wersji, zmieniany przy radykalnych zmianach w budowie jądra. Pierwsze wersje Linuksa miały (krótko) numer 0, następnie przez długi czas 1; obecna główna wersja to 4.
Druga liczba (Y) – linia bądź seria jądra, parzyste liczby oznaczają wersję ‘stabilną’; nieparzyste – ‘rozwojową’. W wersjach rozwojowych testowane są nowe koncepcje, które później są ewentualnie przenoszone do wersji stabilnych. Wersje stabilne są też stale poprawiane, więc w pewnym sensie także się rozwijają.
Trzecia liczba (ZZ), to wersja jądra w danej linii, cały numer wyznacza ‘wydanie’ (release).
Dodatkowo, wydania mogą być oznaczane różnymi przyrostkami, przede wszystkim określającymi rodzaje łatek na nie nałożonych lub numer wersji testowej. Przyrostek “pre” oznacza wersję beta, np. 2.4.20pre7 oznacza 7 wersję beta kernela 2.4.20 . Po zakończeniu testowania ten kernel otrzyma numer 2.4.20, bądź przekształci się w 2.4.20pre8, jeżeli Linus nie zatwierdzi wersji jako oficjalnego wydania.
Zdarzają się też przyrostki oznaczające jądra tworzone równolegle do “oficjalnego” (zatwierdzanego przez Linusa Torvaldsa) jądra, np.:
arca – tworzone przez Andree Arcangeli,
ac – tworzone przez Alana Coxa, np. 2.0.36-ac12.
Numery wersji dla jądra 2.6 i 3+¶
Począwszy od serii 2.6 zrezygnowano z “dużych” serii rozwojowych o numerach nieparzystych na rzecz bardziej ciągłego rozwoju. W serii 2.6, numery wersji są postaci 2.6.XX.YY. Trzecia liczba (XX) oznacza wersję jądra w danej linii, jest ona zmieniana gdy dodane zostaną nowe sterowniki bądź nowa funkcjonalność. Nowe wydanie jądra różniące się od poprzedniego wyłącznie poprawkami błędów mają numer różniący się czwartą liczbą (YY). Oczywiście istnieją też jądra wydawane przez kogoś innego niż Linus Torvalds, zazwyczaj ich nazwa kończy się jakimś przyrostkiem.
W lipcu 2011 została wydana wersja 3.0, rozpoczynająca nową serię. W tej serii, numery wersji są postaci 3.XX.YY, gdzie XX i YY oznaczają to samo co w serii 2.6. Zmiana ta nie wiązała się z żadną nową funkcjonalnością, a z 20 rocznicą powstania Linuksa – wersja 3.0 nie różni się bardziej od 2.6.40 niż 2.6.40 od 2.6.39. Przejście na nowy system numeracji zostało przeprowadzone ze względu na nieadekwatność starego systemu do nowego modelu rozwoju jądra – numery wersji były po prostu za długie. Od tego czasu, główny numer wersji po prostu jest zwiększany, gdy numer drugorzędowy stanie się “dostatecznie duży” – nie ma to związku z funkcjonalnościami i ilością wprowadzonych zmian. W kwietniu 2015 została wydana wersja 4.0 (po wersji 3.19). W 2019 została wydana wersja 5.0 (https://lkml.org/lkml/2019/3/3/236).
Pobieranie źródeł jądra¶
Najprostszym sposobem zdobycia źródeł jądra jest pobranie skompresowanego
pliku .tar ze strony http://kernel.org/, będącej oficjalnym archiwum wydań
jądra. Oprócz kompletnych paczek ze źródłemi, publikowane są również łaty
(pliki .patch
),
umożliwiające zaktualizowanie wcześniej ściągniętej paczki do nowszej wersji.
Trochę bardziej skomplikowanym, lecz znacznie elastyczniejszym sposobem zdobycia źródeł jest użycia gita. Pozwala to na pracę na najświeższym kodzie (nie zawartym jeszcze w żadnym oficjalnym wydaniu), a także niemal natychmiastowe przemieszczanie się między wszystkimi dotychczasowmi wersjami zawartymi w historii (od 2.6.12). Użycie gita jest też wymagane w przypadku wysyłania własnych zmian do włączenia do oficjalnej wersji jądra.
Istnieje wiele repozytoriów gita ze źródłami Linuksa – każdy podsystem jest rozwijany w swoim własnym repozytorium, które jest następnie łączone z głównym repozytorium, gdy nadchodzi czas na wydanie nowej wersji. Główne repozytorium, należące do Linusa Torvaldsa i używane jako podstawa do nowych wydań jądra, znajduje się pod adresem
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Wszystkie “duże” wydania (2.6.XX, 3.XX, 4.XX) oraz wydania release candidate są w nim dostępne jako tagi (v2.6.27, v3.1-rc3, itd). Wydania będące poprawkami błędów (2.6.XX.YY, 3.XX.YY) są natomiast tworzone w osobnym repozytorium, dostępnym pod adresem
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
Jeśli chcemy pracować tylko nad zewnętrznymi modułami jądra, nie modyfikując
istniejącego kodu, posiadanie kompletnych źródeł nie jest konieczne.
Wystarczą nagłówki jądra, zainstalowane najczęściej w /usr/src/linux
i podlinkowane w /lib/modules/<wersja>/build
. Muszą to jednak być prawdziwe
nagłówki jądra, a nie te przeznaczone do użytku przez libc. Wersja jądra,
z której pochodzą te nagłówki musi się również dokładnie zgadzać z wersją
jądra, pod którą będą używane skompilowane moduły. Niektóre dystrybucje
pakują takie nagłówki w osobnej paczce, nazwanej np. linux-headers.
Dystrybucje często posiadają również źródła jądra w standardowym repozytorium pakietów – takie źródła zazwyczaj zawierają jednak łaty nakładane przez dystrybucję i nie są identyczne z oficjalnym wydaniem.
Nakładanie łat (patches) na źródła jądra¶
Zamiast pobierania całej nowej paczki z kodem jądra, można nałożyć łaty (pliki o nazwie
np. patch-xx.xx.xx.gz
) na stare źródła poleceniem patch, np.
cd /usr/src/linux
gzip -cd patch.xx.xx.xx.gz | patch -p1
Można też użyć do tego skryptu patch-kernel
, znajdującego się w katalogu
scripts
(automatycznie aplikuje łaty znalezione w katalogu, z którego został
wywołany).
Łaty ‘oficjalne’ o nazwie np. patch-2.6.17.14.gz
działać będą z poprzednim
wydaniem (względem nazwy określonej w nazwie patcha), czyli wspomniana łata
działać będzie z jądrem 2.6.17.13. Łaty nieoficjalne (np.
patch-2.6.11-ac4.gz
) zazwyczaj odnoszą się to tego samego wydania co w
nazwie.
Przed zainstalowaniem nowego jądra należy zapoznać się z plikiem
Documentation/Changes
, który zawiera wymagania odnośnie wersji
kompilatora, zainstalowanych pakietów, wersji bibliotek, itp. i upewnić się,
że stosowne wersje ma się zainstalowane.
Struktura źródeł jądra¶
Zawartość głównego katalogu¶
- Documentation
katalog zawierający dokumentacje, w szczególności należy się zapoznać z plikiem
CodingStyle
- arch
kod źródłowy zależny od architektury procesora
- block
funkcje warstwy urządzeń blokowych (ang. kernel block layer)
- crypto
funkcje kryptograficzne (a także kompresja i dekompresja)
- drivers
sterowniki urządzeń
- firmware
kod pomocniczy ładowany przez niektóre sterowniki urządzeń na kontrolowane przez nie urządzenia
- fs
systemy plików
- include
pliki nagłówkowe
- init
niezależna od platformy część inicjalizacji systemu
- ipc
IPC (komunikacja międzyprocesowa System V)
- kernel
rdzeń jądra – zarządzanie procesami, przerwania, DMA, czas
- lib
procedury pomocnicze (np. wypisywanie na ekran, rozpakowywanie spakowanego jądra)
- mm
zarządzanie pamięcią
- net
protokoły sieciowe
- samples
przykłady użycia niektórych wewnętrznych interfejsów jądra
- scripts
skrypty (np. do konfiguracji)
- security
kod związany z bezpieczeństwem (LSM – Linux Security Modules)
- sound
sterowniki kart dźwiękowych oraz kod obsługujący dźwięk (ALSA)
- usr
programy pomocnicze; aktualnie gen_init_cpio służący do tworzenia ramdysku ładowanego razem z jądrem systemu.
- virt
kod związany z wirtualizacją (KVM)
arch – kod zależny od platformy sprzętowej¶
Kod dla procesorów Intela znajduje się w katalogu arch/x86
. Istnieje
możliwość skompilowania jądra dla innego procesora niż ten, na którym pracujemy,
jakkolwiek wymaga to (poza źródłami Linuksa) także kompilatora dla danej
platformy, działającego na naszym systemie (tzw. cross-compiler).
Nagłówki jądra¶
Jądro zawiera dwa zbiory nagłówków: wewnętrzne oraz nagłówki dla przestrzeni
użytkownika. Nagłówki wewnętrzne są przeznaczone tylko do użytku przez sam
kod jądra oraz moduły i są instalowane w /usr/src/linux
(o ile w ogóle).
Nagłówki dla przestrzeni użytkownika znajdują się w podkatalogach o nazwie
uapi
i są przeznaczone do użytku zarówno przez kod jądra, jak i przez
programy użytkownika. Te nagłówki są instalowane w /usr/include
.
Ze względu na gwarancje kompatybilności interfejsów jądra, zainstalowana
wersja nagłówków może być różna od wersji używanego jądra.
Wewnątrz źródeł jądra, nagłówki są porozrzucane po wielu katalogach:
include
: główne nagłówki jądrainclude/generated
: główne nagłówki jądra, wygenerowane w czasie kompilacjiarch/<procesor>/include
: nagłówki jądra specyficzne dla danej architekturyarch/<procesor>/include/generated
Z ważniejszych podkatalogów z nagłówkami należy wymienić asm
, asm-generic
oraz linux
.
Konfiguracja jądra¶
Przed kompilacją, źródła jądra muszą zostać skonfigurowane za pomocą jednego z poniższych poleceń:
make config
(wersja tekstowa, zadaje jedno pytanie na każdą opcję – niezalecane),make menuconfig
(ncurses),make xconfig
(X11),make oldconfig
(jakmake config
, ale aktualizuje konfigurację ze starej wersji jądra – pyta tylko o nowe opcje)
Najprostsza w obsłudze jest wersja menuconfig
, bądź xconfig
, choć
w tej ostatniej częściej zdarzają się błędy.
Poniższe punkty opisują istotne elementy konfiguracji (tytuły odpowiadają
elementom głównego menu w menuconfig
).
Warning
Opcje jądra miewają dośc skomplikowane zależności, a programy konfigurujące
nie pokazują opcji, które są wykluczone przez inne wybory (np. jeśli nie
włączyliśmy wsparcia dla urządzeń typu virtio w opcjach wirtualizacji,
w ogóle nie zobaczymy opcji wsparcia wirtualnej karty sieciowej virtio-net
w opcjach sterowników sieci). Jeśli nie jesteśmy w stanie znaleźć poszukiwanej
opcji tam, gdzie się jej spodziewamy, warto użyć funkcji wyszukiwania
(wystarczy nacisnąć /
w make menuconfig
) – wyniki pokażą nam, gdzie
opcja jest w drzewie wyborów oraz od jakich opcji zależy.
64-bit kernel¶
Wybiera, czy skompilowane jądro będzie działało w trybie 64-bitowym i zarazem pozwalało na uruchamianie 64-bitowych programów (uruchamianie 32-bitowych programów jest zawsze możliwe, chyba że jawnie wyrzucimy tą opcję w dalszej konfiguracji).
General setup¶
Ta część konfiguracji kontroluje kluczowe komponenty jądra systemu Linux. Najważniejsze opcje to:
‘Support for paging of anonymous memory (swap)’ – obsługa pamięci wirtualnej na dysku
‘System V IPC’ – obsługa komunikacji międzyprocesowej
‘Initial RAM filesystem and RAM disk (initramfs/initrd) support’ – umożliwia wystartowanie Linuksa z ramdysku ładowanego przed uruchomieniem (np. przez GRUBa), co pozwala na załadowanie sterowników dla dysków czy systemów plików dostępnych tylko jako moduły lub też start systemu z urządzeń software-RAID.
‘Initramfs source file(s)’ – lista plików do załączenia w ramdysku
‘Embedded system’ – sama w sobie nic nie zmienia, ale powoduje pojawienie się opcji pozwalających na wyłączenie funkcjonalności zazwyczaj uznawanych za konieczne.
Enable loadable module support¶
Note
Moduł – część kodu jądra, która może być ładowana lub usuwana z jądra na życzenie. Wszystkie części jądra, które nie są potrzebne przy starcie systemu i nie są ciągle używane w trakcie pracy systemu powinny być skompilowane jako moduły. Nawet wiele części potrzebnych przy starcie systemu może być modułami, musimy tylko użyć ramdysku (initial ramdisk).
Konfiguruje wsparcie dla modułów jądra. W zależności od potrzeb, możemy włączyć lub wyłączyć ładowanie modułów (Enable loadable module support), umożliwić usuwanie modułów (Module unloading, Forced module unloading), umożliwić automatyczne ładowanie modułów przez kernel (Automatic kernel module loading) oraz umożliwić ładowanie modułów skompilowanych dla innych wersji jądra dzięki umieszczaniu w nich dodatkowych informacji o potrzebnych funkcjach (Module versioning support). Możemy też umieścić w każdym module sumę kontrolną (Source checksum for all modules).
Processor type and features¶
Umożliwia skonfigurowanie wsparcia i optymalizacji jądra dla danego procesora (Processor family) – w razie niepewności dla architektury i386 bezpiecznymi rozwiązaniami są 386 (zawsze) i 586 (dla procesorów od pentium w górę) bądź Pentium (dla procesorów Intela od pentium w górę). Uwaga – w przypadku wybrania nieprawidłowej wartości jądro może nie działać bądź działać błędnie. Inne ważne opcje dostępne w tym menu to:
‘High Memory Support’ – wsparcie dla systemów z >1GB pamięci (tylko 32-bit),
‘Math emulation’ – emulacja jednostki 387 dla starych procesorów bez FPU,
‘MTRR (Memory Type Range Register) support’ – obsługa rejestrów dostępu do pamięci, umożliwiająca ustawienie szyny PCI/AGP w tryb “write-combining”, co może znacznie przyspieszyć aplikacje graficzne.
‘Symetric multi-processing support’ – wsparcie dla wielu procesorów
‘SMT (Hyperthreading) scheduler support’ – polepszenie właściwości planisty dla systemów z procesorem z obsługą HT.
‘Preemption Model’ – pozwala wybrać, czy jądro może być wywłaszczane.
‘Local APIC support on uniprocessors’ – wsparcie dla zaawansowanych kontrolerów przerwań dostępnych w nowszych płytach głównych. Opcja ta dostępna jest tylko, jeśli SMP jest wyłączone (dla systemów SMP APIC i tak zawsze jest włączone).
Power management and ACPI options¶
Wybór obsługiwanych metod oszczędzania energii – w tym obsługa ACPI oraz zmian prędkości procesora w trakcie działania systemu.
Bus options (PCI etc.)¶
Wybór obsługiwanych szyn systemowych oraz ich parametrów. Dla współczesnych komputerów warto skonfigurować obsługę szyny PCI.
Executable file formats / Emulations¶
Obsługa formatów plików wykonywalnych. Bez obsługi formatu ELF z tradycyjnymi dystrybucjami Linuksa zbyt wiele nie da się zrobić. W przypadku jądra 64-bitowego możemy tutaj włączyć lub wyłączyć obsługę 32-bitowych programów.
Networking support¶
Zazwyczaj nie daje się, całe szczęście, wyłączyć obsługi sieci (Networking support), bo bez tego niewiele by działało. Oprócz opisanego poniżej menu Networking options można tu skonfigurować obsługę różnych metod komunikacji - przez podczerwień, Bluetooth, Wi-Fi.
Networking options¶
Menu to zawiera konfigurację komponentów sieciowych i protokołów. Najważniejsze z nich to:
- ‘Packet socket’
bezpośredni dostęp do urządzeń sieciowych.
- ‘Unix domain sockets’
gniazda Unixowe, umożliwiające komunikację międzyprocesową w sposób zbliżony do komunikacji sieciowej. Gniazda takie są wykorzystywane np. przez X-Windows, PostgreSQL.
- ‘TCP/IP Networking’
obsługa protokołu TCP/IP – bardzo ważne. Ale trudne do niewybrania.
- ‘The IPv6 protocol’
obsługa nowej wersji protokołu TCP/IP. Obecnie jeszcze niekonieczna, ale za jakiś czas zapewne nie będzie się można bez tego obejść.
- ‘Network packet filtering framework (Netfilter)’
filtrowanie i modyfikowanie pakietów (firewall, NAT).
Device Drivers¶
Różne ustawienia dotyczące sterowników pogrupowane w wielu menu.
W przypadku budowania jądra na potrzeby zajęć najlepiej jest wybrać tylko niezbędne sterowniki – przyspieszy to znacząco proces budowy jądra.
Block devices¶
Najważniejsze opcje to:
- ‘Loopback device support’
pseudourządzenie umożliwiające stworzenie ‘urządzenia’ blokowego którego zawartość przechowywana jest w zwykłym pliku.
- ‘RAM block device support’
wsparcie dla RAM dysków.
- ‘Packet writing on CD/DVD media’
umożliwia zapis dysków CD/DVD
- ‘Virtio block driver’
wirtualizowane urządzenie blokowe o niskim narzucie
NVM Express block device¶
Wsparcie dla dysków SSD montowanych bezpośrednio na płycie głównej (złącze M.2).
SCSI device support¶
Włącza przede wszystkim obsługę magistrali SCSI, ale także umożliwia obsługę wielu innych rodzajów urządzeń blokowych używających emulacji SCSI (w tym SATA, ATA i USB). Do działania tych urządzeń należy włączyć opcje ‘SCSI disk support’, ‘SCSI CD-ROM support’, ‘SCSI generic support’. Dodatkowo w menu ‘SCSI low-level drivers’ można włączyć obsługę sprzętowego kontrolera SCSI (o ile takowy jest potrzebny/zainstalowany).
Serial ATA and Parallel ATA drivers (libata)¶
Obsługa urządzeń dyskowych ATA i SATA. Należy tu też wybrać posiadany kontroler ATA bądź SATA. Opcje ‘AHCI SATA Support’ oraz ‘Generic ATA support’ obsługują większość urządzeń, lecz mogą mieć mniejszą funkcjonalność niż specjalistyczny sterownik. Ten sterownik jest zrobiony na bazie warstwy SCSI – aby skorzystać z dysku bądź napędu optycznego, należy również włączyć wsparcie dla odpowiedniego typu urządzenia w menu SCSI.
Multiple devices driver support (RAID and LVM)¶
- ‘RAID support’
włącza obsługę programowego RAID, umożliwiającego wykorzystanie wielu dysków jako jeden, co może zwiększyć wydajność i bezpieczeństwo operacji dyskowych.
- ‘Device mapper support’
obsługa niskopoziomowego manadżera woluminów, z którego korzystają programy umożliwiającego definiowanie zbiorów urządzeń (volume group) a na nich logicznych dysków (woluminów) dla uproszczenia zarządzania dyskami w dużych systemach.
Opcja ‘RAID support’ przydatna jest także w systemach domowych, pod warunkiem posiadania co najmniej dwóch dysków twardych – w takiej sytuacji tryb RAID-0 umożliwia dwukrotny wzrost wydajności operacji dyskowych.
Network device support¶
Umożliwia kompilację sterownika karty sieciowej (‘Ethernet (10 or 100Mbit)’, ‘Ethernet (1000 Mbit)’), bezprzewodowej karty sieciowej (‘Wireless LAN’) i obslugę PPP (‘PPP (point-to-point protocol) support’), jak również wielu innych typów kart sieciowych oraz protokołów. Te cztery opcje jednak będą najczęściej wykorzystywane.
Input device support¶
Wsparcie (ogólne) dla urządzeń wejściowych. Jeżeli chcemy korzystać z myszki, klawiatury, joysticka lub podobnych urządzeń, należy włączyć tę opcję (szczęśliwie trudno ją wyłączyć) oraz odpowiedni moduł. Obsługa urządzeń wejściowych USB znajduje się w menu ‘HID Devices’ (patrz niżej).
Character devices¶
Najważniejsza opcja to ‘Virtual Terminal’, umożliwiająca korzystanie z konsoli Linuksa. Jest domyślnie niewidoczna i włączona (wyłączyć ją można tylko dla systemów wbudowanych). Można tu również włączyć obsługę portów szeregowych.
Graphics support¶
Wybór obsługiwanych urządzeń graficznych oraz w menu ‘Console display driver support’ obsługa konsoli. ‘VGA text console’ umożliwia obsługę konsoli na urządzeniu typu VGA. Znajdują się tu również przyspieszane sprzętowo sterowniki graficzne (Direct Rendering Manager).
Sourd card support¶
Wybór obsługiwanych systemów dźwiękowych oraz sterowników kart dźwiękowych. Zaleca się użycie systemu ALSA (Advanced Linux Sound Architecture).
HID support¶
Wsparcie dla urządzeń typu HID – przede wszystkim klawiatury i myszy podłączane przez USB.
USB support¶
Tu można wybrać obsługiwane chipsety oraz urządzenia podłączane przez magistralę USB. ‘USB Mass Storage support’ umożliwia korzystanie z urządzeń pamięci masowej, w tym dysków i pamięci flash. Wiele urządzeń USB znajduje się w innych kategoriach – np. karty sieciowe w ‘Network device support’.
Virtio drivers¶
Włącza wsparcie dla urządzeń virtio – wirtualnych urządzeń o małym narzucie, dostarczanych przez QEMU. Warto włączyć tą opcję, gdy kompilujemy jądro dla maszyny wirtualnej. Część sterowników virtio można znaleźć w innych miejscach (np. virtio network device jest wśród innych kart sieciowych).
Pozostałe sekcje ze sterownikami¶
W pozostałych menu można skonfigurować różnorakie urządzenia znajdujące się w systemie. Zazwyczaj można je spokojnie skompilować jako moduły, ponieważ nie są one potrzebne do startu systemu.
File systems¶
Umożliwia włączenie obsługi różnorakich systemów plików. Najważniejsze to system który używany jest na partycji startowej systemu (najczęściej ext4 bądź btrfs) – musi on być wkompilowany w jądro bądź załączony na ramdysku. Pozostałe systemy plików można skompilować jako moduły. Ważna jest również obsługa ‘Tmpfs virtual Memory file system support’, konieczne są ‘/proc’ oraz sysfs (wszystkie z ‘Pseudo filesystems’). ‘Filesystem in Userspace support’ to FUSE, pozwalający na używanie systemów plików działających w przestrzeni użytkownika. Pozostałe systemy plików można skompilować w zależności od potrzeb.
Kompilacja jądra – Kbuild¶
Kbuild jest systemem budowania Linuksa. Składa się on z odpowiednio przygotowanych Makefile’i.
Tak jak zawsze przy Makefile’ach używa się go następująco:
make <opcje> <cel> <opcjonalne zmienne dla Kbuild>
Użyteczną opcją do make jest -j<N> – spowoduje zrównoleglenie kompilacji aż do <N> procesów jednocześnie (proszę nie nadużywać tego na students).
- make clean
Usuwa skompilowane pliki.
- make bzImage
Kompiluje jądro i umieszcza je w katalogu
arch/<architektura>/boot
pod nazwa bzImage. Jądro tak utworzone jest skompresowane (rozpakowuje się przy starcie systemu).- make modules
Kompiluje części jądra, które skonfigurowaliśmy jako moduły. Następnie należy je zainstalować poleceniem
make modules_install
.- make all
Ma takie działanie, jak
make bzImage
razem zmake modules
.- make modules_install
Instaluje moduły do katalogu
/lib/modules/<wersja>/
i wywołujedepmod
w celu stworzenia informacji o zależnościach. Jeżeli podana jest zmiennaINSTALL_MOD_PATH
, instaluje w$INSTALL_MOD_PATH/lib/modules/<wersja>/
.- make help
Pokazuje dostępne polecenia
make
.- make mrproper
Czyści dokładnie katalog ze źródłami (łącznie z konfiguracją!), usuwa też zależności, moduły, itp.
- make prepare
Przygotowuje docelowy katalog do budowania. Szczególnie przydatne przy budowaniu w innym katalogu niż źródła.
- make install
Instaluje jądro i dodaje je do konfiguracji bootloadera, nie zawsze działa zgodnie z oczekiwaniami.
- make htmldocs
Kompiluje dokumentację w formacie DocBook do formatu HTML.
- make pdfdocs
Kompiluje dokumentację w formacie DocBook do formatu PDF.
- make rpm
Tworzy pakiet RPM z jądrem (przydatne w systemie RedHat).
Zmienne¶
Niektóre parametry kompilacji jądra można podawać przez zmienne programu
make (dopisując ZMIENNA=wartość
na koniec polecenia make). Te najważniejsze:
- V=1
Verbose, Kbuild wypisze dokładniej co robi.
- ARCH=<arch>
Wymuszenie architektury
<arch>
, np. i386.- EXTRA_CFLAGS=<flagi>
Podczas kompilacji,
<flagi>
będą dodane do wywołań gcc (użyteczne może być podanie-g
, żeby mieć symbole).- INSTALL_MOD_PATH=<ścieżka>
Instaluje moduły w podanej lokalizacji.
- O=<ścieżka>
Umieszcza pliki wynikowe w osobnym katalogu; po pierwszym wywołaniu make z tą opcją, następnie można używać make we wskazanym katalogu bez dodatkowych opcji (jest tam umieszczony odpowiedni Makefile).
Ćwiczenie¶
Skonfigurować i skompilować jądro i moduły, a następnie umieścic jądro w
katalogu /boot
.
Należy pamiętać o włączeniu wszystkich opcji koniecznych do wystartowania systemu, m.in.:
zaznaczyć 64-bit kernel
obsługa szyny PCI (Bus options -> PCI support)
obsługa formatu ELF (Exectable file formats -> Kernel support for ELF binaries)
obsługa virtio (Device drivers -> virtio -> PCI driver for virtio devices)
obsługa virtio balloon (Device drivers -> virtio -> Virtio balloon driver)
obsługa gniazd lokalnych (Network support -> Networking options -> Unix domain sockets)
obsługa protokołu IPv4 (Network support -> Networking options -> TCP/IP networking)
sterownik virtio block (Device drivers -> Block devices -> Virtio block driver)
sterownik virtio net (Device drivers -> Network device support -> Virtio network driver)
sterownik virtconsole (Device drivers -> Character devices -> Virtio console)
system plików ext4 (File systems -> The Extended 4 (ext4) filesystem)
system plików proc (File systems -> Pseudo filesystems -> /proc file system support)
system plików FUSE (File systems -> FUSE (Filesystem in Userspace) support)
Programy ładujące¶
Programy ładujące (bootloadery) ładują system operacyjny. Przy starcie komputera BIOS ładuje do pamięci MBR (master boot record) i przekazuje mu sterowanie. W MBR znajduje się tablica partycji i kod, który może być kodem ładującym system (np. kod ładujacy DOS). Ma on za zadanie załadowac boot sektor z odpowiedniej partycji i przekazac mu sterowanie. Jeśli jednak chcemy zorganizować współistnienie kilku systemów na jednym dysku, umieszczamy w MBR kod programu ładującego, który pozwala wybrać przy starcie, który boot sektor ma byc wczytany. Przykładami takich programów ładujących (dla systemu Linux na architekturze x86) są:
grub: pozwala na uruchamianie systemu z dysku twardego, bezpośrednio obsługuje szeroki zakres systemów plików i tablic partycji. Oprócz jądra systemu Linux wspiera również standard multiboot, FreeBSD/OpenBSD/NetBSD, oraz ładowanie innych bootloaderów (tzw. chain-loading). Posiada dość rozbudowaną linię poleceń pozwalającą m.in. na przeglądanie systemu plików i modyfikację linii poleceń uruchamianego jądra.
grub2: bardziej modularny i rozbudowany następca gruba, wypierający już oryginał.
syslinux: w zasadzie pakiet kilku lekkich bootloaderów:
syslinux: pozwala na uruchomienie systemu Linux z partycji dysku, rzadko stosowany.
isolinux: uruchamia system z płyt CD używających system plików ISO 9660.
pxelinux: uruchamia system przez sieć, używając środowiska PXE.
lilo: niegdyś bardzo popularny bootloader napisany dla systemu Linux, dziś już przestarzały
GRUB¶
GRUB dostępny jest poprzez dwa interfejsy: dający więcej możliwości interfejs linii komend bądź proste menu. Zwykle to drugie wystarcza. Po starcie, GRUB szuka pliku konfiguracyjnego. Jeśli go znajdzie, wyświetla pozycje z tego pliku (odpowiadające obrazom Linuksa bądź innym systemom) w formie pozycji menu. Pozycje menu można edytować (ale zmiany mają wpływ tylko na dane uruchomienie, nie są zapamiętywane) – przejście do trybu edycji odbywa się przez wciśnięcie ‘e’ (i w ten sposób być może da się naprawić błędy z pliku konfiguracyjnego). Z menu można również przejść do linii komend poprzez wciśnięcie ‘c’ (powrót przez ESC). Jeśli nasz GRUB jest chroniony hasłem, przejście do trybu edycji czy linii komend możliwe jest tylko po wcześniejszym naciśnięciu ‘p’ i wprowadzeniu hasła.
Plikiem konfiguracyjnym GRUB-a jest /etc/grub.conf
. Plik składa się
z wpisów dla kolejnych obrazów jądra czy innych systemów operacyjnych.
Kolejne wpisy są numerowane poczynając od 0.
Najważniejszymi komendami wchodzącymi w skład wpisu są:
TITLE nazwa_obrazu
– nazwa, która będzie widoczna w menu. Rozpoczyna wpis; wpis kończy się z końcem pliku lub z wystąpieniem kolejnej komendytitle
(zaczynającej następny wpis).ROOT root_device
– gdzie będziemy szukać obrazu.ROOTNOVERIFY root_device
– jak wyżej, ale urządzenie nie zostanie zamontowane, a komenda służy zwykle podaniu położenia innego boot loadera, co pozwala na tzw. chain-loading i ładowanie np. Windowsów.KERNEL plik_z_obrazem [opcje_dla_jądra]
Istotnymi komendami wchodzącymi ponadto w skład grub.conf
są:
DEFAULT=numer_wpisu
– który wpis będzie wybrany domyślnie (jeśli nie jest podany, wybrany będzie wpis 0).TIMEOUT=ile_sekund
– GRUB będzie czekałile_sekund
na wybór systemu. Jeśli to nie nastąpi, zacznie ładować domyślny.
Znakiem #
rozpoczynają się linie komentarza.
Plik grub.conf
mógłby wyglądać np. tak:
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/hda2
default=1
timeout=3
title dos
rootnoverify (hd0,0) # ustawia GRUB root device, bez montowania
makeactive
chainloader +1 # ładuje boot loader
title linux
root (hd0,4)
kernel /vmlinuz ro root=/dev/hda5 hdc=ide-scsi
title nowe
root (hd0,4)
kernel /vmlinuz-2.2.17 ro root=/dev/hda5 hdc=ide-scsi
GRUB 2¶
GRUB 2 jest następcą GRUBa, o większej modularności i funkcjonalności. Interfejs menu jest dość podobny do GRUBa, ale znacznie zmieniona została konfiguracja.
Plikiem konfiguracyjnym GRUBa 2 jest /boot/grub/grub.cfg
, ale nie należy
go modyfikować bezpośrednio – jest on generowany przez program grub-mkconfig
na podstawie skryptów w katalogu /etc/grub.d
i konfiguracji w pliku
/etc/default/grub
.
Dzięki skryptom konfiguracyjnym, nie trzeba ręcznie tworzyć wpisów
konfigracyjnych dla każdego jądra – wystarczy umieścić jądro jako
/boot/vmlinuz-<wersja>
, a ewentualny
initramfs jako /boot/initrd.img-<wersja>
. Opcje przekazywane zainstalowanemu
jądru można ustawić w pliku /etc/default/grub
.
Po zmianie konfiguracji należy wydać polecenie:
grub-mkconfig -o /boot/grub/grub.cfg
Aby zainstalować GRUBa 2 po raz pierwszy należy wydać polecenie:
grub-install /dev/<dysk>
Ćwiczenie¶
Zmodyfikować plik
/etc/grub.conf
, tak żeby umożliwiał załadowanie nowo stworzonego obrazu.Zrestartować komputer, poprosić bogów o wsparcie i uruchomić nowo utworzone jądro.