Zrób własny moduł jądra Linuksa
A
A
A
rozmiar czcionki
Określenie "napisać własny moduł jądra Linuksa" brzmi poważnie. Może się wydawać się, że moduły jądra piszą tylko starzy hakerzy - ci sami, którzy projektują własne procesory i używają IPv6. To nieprawda. Jeśli umiesz programować w C, możesz szybko zwiększyć możliwości systemu spod znaku pingwina.
Chcesz, żeby Winamp odtwarzał muzykę w jakimś egzotycznym formacie? Możesz napisać wtyczkę, która rozszerzy jego funkcjonalność. Będzie to osobny plik, który Winamp ładuje przy starcie. W rezultacie w menu pojawiają się dodatkowe opcje, aplikacja zaczyna "rozumieć" formaty dotychczas dla niej nieczytelne albo podejmuje zupełnie nowe działania, np. wysyła pliki z muzyką przez Gadu-Gadu, pobiera teksty piosenek itp.
W podobny mechanizm jest wyposażony Linux. Jeśli chcesz dodać do niego nową funkcję, możesz napisać moduł jądra. W ten sposób można dodać obsługę nowego sprzętu, systemu plików - niemal wszystko, co przyjdzie ci do głowy. W artykule powiemy, na czym to polega i od czego zacząć.
Czym się zajmiemy
Jakiś czas temu bawiliśmy się w pisanie w różnych językach programowania klasycznej gry "Pomidor" (smupo.achjoj.info/gra_w_pomidora). Znasz ją, prawda? Zasady są proste - jedna osoba mówi cokolwiek, a druga odpowiada jedynie "pomidor". Zaimplementujemy tę grę jako moduł jądra. Będzie działać tak, że na wszystko, co wyślesz kernelowi Linuksa, odpowiedzią będzie "pomidor".
Zakładamy, że już umiesz
W tym artykule zakładamy, że znasz C na tyle, aby zrozumieć oraz skompilować i uruchomić w Linuksie poniższy program:
#include
void hello() {
printf("Hello world!\n");
}
int main() {
hello();
}
Jak wygląda moduł
Przypomnijmy sobie, jak wyglądają i działają moduły jądra w środowisku linuksowym. Są to pliki z rozszerzeniem .ko w nazwie. Chcąc załadować moduł, należy wydać (jako root) polecenie insmod modul.ko.
Aby zobaczyć, jakie moduły są załadowane, wydaj polecenie lsmod, a żeby wyrzucić z pamięci załadowany moduł, zastosuj rmmod modul.
Środowisko
Aby kompilować moduły jądra, musisz mieć źródła jądra, którego używasz, oraz tę wersję kompilatora (gcc), która była użyta do jego skompilowania. W Debianie wystarczy zainstalować ostatnią wersję trzech pakietów: gcc, linux-image-2.6.jakaś_wersja i linux-headers-2.6.jakaś_wersja.
Do pisania modułów możesz używać dowolnego edytora tekstu, a najwygodniej przetestujesz je w konsolą tekstowej (nie w Xtermie czy innym emulatorze terminala). Dzięki temu, kiedy jądro prześle do dziennika komunikat, od razu zobaczysz go na ekranie.
Na dołączonej do pisma płycie CD zamieściliśmy wirtualną maszynę, na której zainstalowany jest Debian ze wszystkim, czego potrzebujesz, żeby pisać i testować moduły opisane artykule. Najwygodniej będzie, jeśli skorzystasz właśnie z niego: eksperymenty z jądrem mogą mieć poważne konsekwencje, z uszkodzeniem danych i sprzętu włącznie. Hasłem roota w tym obrazie jest root.
Pierwszy moduł
Na początek utworzymy prosty moduł - taki, który niczego nie robi, ale da się skompilować, załadować i usunąć.
Utwórz plik o nazwie pomidor.c i takiej treści:
#include
int init_module(void) {
return 0;
}
void cleanup_module(void) { }
Utwórz też plik o nazwie Makefile i treści:
obj-m += pomidor.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Zanim spróbujesz go skompilować, przyjrzyj mu się. Składa się z dwu funkcji. Pierwsza z nich - init_module() - zostanie wywołana przez jądro w chwili załadowania modułu. Druga - cleanup_module() - będzie wykonana w chwili usunięcia go z pamięci. Jak widać, w naszym najprostszym module obie te funkcje nie robią nic.
Pliku Makefile nie analizujmy, przyjmijmy, że ma tak właśnie wyglądać i że w jego pierwszym wierszu powinna się znaleźć nazwa modułu, czyli w naszym przykładzie pomidor.o.
Aby skompilować ten moduł, wydaj polecenie make. Zobaczysz komunikaty kompilatora, a następnie w katalogu pojawi się kilka nowych plików - wśród nich sam skompilowany moduł pomidor.ko. Załadowanie go do pamięci będzie dziecinnie proste, wystarczy, że wydasz polecenie insmod pomidor.ko. Kiedy wkorzystasz polecenie lsmod do wyświetlenia listy zainstalowanych modułów, z pewnością dostrzeżesz na niej moduł o nazwie "pomidor". Możesz go zatem usunąć: rmmod pomidor.