Wstęp
Pierwszym procesem uruchomionym po starcie kernela jest proces init, posiada on identyfikator(PID, process ID) 1 i jest rodzicem dla wszystkich procesów uruchomionych później w systemie. Jeśli init nie zostanie znaleziony lub nie może być uruchomiony kernel rzuci błędem „Kernel panic” co było widoczne w lekcji dotyczącej kernela. Podczas startowania systemu program init, który ma zostać uruchomiony może zostać wskazany w parametrach kernela za pomocą opcji „init=/ścieżka/do/programu/init”. System może być uruchomiony dopóki działa proces o PIDzie 1, wydanie komendy:
kill 1
Ta komenda powinna być równoznaczna z resetem lub wyłączeniem urządzenia. Przetestuj to na swojej platformie.
Obecnie programy init są dostarczane przez init systemy. Init systemy oprócz tego, że odgrywają rolę pierwszego procesu w systemie umożliwiają również zarządzanie serwisami czy jak kto woli demonami systemowymi.
Do najpopularniejszych init systemów należą:
- BusyBox- jest to mały system o stosunkowo małych możliwościach, często jest wykorzystywany na systemach wbudowanych
- System V init- do niedawna to ten init system królował w zastosowaniach desktopowych czy serwerowych teraz został wyparty przez nowszy systemd. BusyBox jest w zasadzie ograniczoną wersją System V przystosowaną do małych urządzeń
- systemd- jest to obecnie najpopularniejszy init system w zastosowaniach desktopowych(jest jakiś dobry polski zamiennik na to słowo?) i serwerowych. Jest to bardzo zaawansowany init system, oprócz tego, że umożliwia zarządzanie demonami umożliwia również synchronizację pomiędzy startowanymi demonami podczas uruchamiania systemu.
Sam osobiście spotkałem się jeszcze z init systemem runit w systemie OpenWRT nie wiem jednak jak wygląda sprawa z jego popularnością. Buildroot oprócz użycia trzech wcześniej wymienionych init systemów umożliwia również użycie OpenRC, jest to init system używany m.in. przez dystrybucje Gentoo.
Jeśli chcesz zmienić init system w Buildrootcie to w menuconfigu musisz przejść zakładki „System configuration”, tam będzie dostępna opcja „Init system”.
Domyślnym wyborem w Buildrootcie jest BusyBox, ze względu na jego prostotę zapoznamy się z nim.
BusyBox
BusyBox podczas uruchamiania używa pliku konfiguracyjnego /etc/inittab. Plik ten definiuje, które programy mają zostać uruchomione i kiedy. Na każdy program przypada jedna linijka pliku w formacie:
terminal::zdarzenie:komenda
Terminal to konsola wyjściowa danego programu, nie trzeba tego parametru podawać, domyślnie będzie to terminal wskazany w parametrach startowych systemu. Można również podać wartość „null” gdy uruchamiamy demona i proces taki z definicji nie jest przypisany do żadnego terminala.
BusyBox umożliwia wykonanie komendy w reakcji na następujące zdarzenia:
- sysinit- wykonanie komendy podczas uruchomienia
- respawn- uruchamia program kiedy ten kończy działanie. Jest to używane razem z demonami
- askfirst- robi to samo co respawn jednak prosi najpierw o potwierdzenie uruchomienia poprzez wciśnięcie entera, jest to używane podczas uruchamiania shella bez potrzeby podawania użytkownika lub hasła
- once- wywołuje komendę raz
- wait- wywołuje komendę i czeka aż ta zakończy działanie
- restart- uruchamia komendę gdy proces init otrzyma sygnał SIGHUP, który informuje BusyBox, że ma przeładować plik inittab
- ctrlaltdel- uruchamia komendę gdy proces init otrzyma sygnał SIGINT
- shutdown- uruchamia komendę gdy proces init kończy działanie czyli najprawdopodbniej podczas wyłączania urządzenia
Możesz trochę poeksperymentować z plikiem /etc/inittab i pododawać do niego np. takie wpisy:
::sysinit:/bin/hello
::respawn:/bin/hello # uwaga, to zaśmieci całą konsolę
::ctrlaltdel:/bin/echo "Łożesz ty! SIGINTem? We mnie" # przetestuj komendą
# kill -2 1
::shutdown:/bin/echo "Si ja lejter!"
Plik /etc/inittab możesz edytować zarówno na uruchomionej platformie jak i podłączyć swoją kartę pamięci(podmontować obraz dysku w przypadku QEMU) i edytować plik na swoim komputerze.
Skrypty BusyBoksa
W katalogu /etc/init.d znajdują się skrypty, które umożliwiają interakcje z serwisami lub uruchomienie/wyłączenie niektórych komponentów jak np. interfejsy sieciowe. Zgodnie z konwencją taki skrypt powinien przyjmować parametry start, stop i opcjonalnie restart.
Zgodnie z inną konwencją skrypty te swoją nazwę zaczynają od litery S po czym następują dwie cyfry, które określają, który w kolejności dany skrypt ma zostać uruchomiony.
W pliku /etc/inittab możesz zobaczyć, że BusyBox uruchamia skrypt /etc/init.d/rcS, który to wykonuje wszystkie skrypty z parametrem start w odpowiedniej kolejności.
Podczas wyłączania BusyBox wywołuje skrypt /etc/init.d/rcK, który to wywołuje wszystkie skrypty w odwrotnej kolejności do kolejności startowania z parametrem stop.
Dla celów instruktażowych możesz utworzyć przykładowy skrypt o nazwie S50Greetings o następującej zawartości:
#!/bin/sh
case "$1" in
start)
printf "System wita\n"
;;
stop)
printf "System zegna\n"
;;
restart|reload)
"$0" stop
"$0" start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit $?
Umieść ten plik w katalogu /etc/init.d. Teraz podczas uruchamiania oraz wyłączania systemu zobaczysz odpowiednią wiadomość. Dodatkowo sam możesz wywołać ten skrypt:
/etc/init.d/S50Greetings start
/etc/init.d/S50Greetings stop