Samouczek sterownika urządzenia Linux dla początkujących

Samouczek sterownika urządzenia Linux dla początkujących
System operacyjny Linux zawiera 3 główne sekcje: system plików root, jądro i bootloader.

System plików głównych:

Ta część systemu operacyjnego zawiera pliki binarne aplikacji, biblioteki, skrypty, pliki konfiguracyjne i pliki modułów ładowania jądra itp

Jądro:

Ta część jest sercem systemu operacyjnego, jądro jest odpowiedzialne za obsługę wszystkich operacji potrzebnych do uruchomienia systemu operacyjnego, takich jak zarządzanie pamięcią, zarządzanie procesami i operacje sprzętowe wejściowe/wyjściowe itp

Program rozruchowy:

To pierwsza część wykonana przez procesor na rozruch. Bootloader zawiera kod źródłowy do zainicjowania systemu i rozpoczęcia wykonania jądra i zawiera polecenia do debugowania i modyfikowania środowiska jądra, zawiera również polecenia do pobrania i aktualizacji obrazów jądra i systemu w pamięci flashowej.

Kierowcy działają jako pomost między sprzętem a aplikacją użytkownika, jądro zapewnia mechanizm zwany połączeniami systemowymi do rozmowy z jądrem. W Linux sterowniki mogą być zaimplementowane na dwa sposoby, jeden jest sterownikiem jako część jądra, a drugi sterowniki można skompilować jako moduły i załadować w czasie wykonywania.

Zacznijmy od prostego modułu jądra Hello World. Oto kod źródłowy prostego modułu jądra Hello World.

Witam.C

#include // potrzebne do module_init i module_exit
#include // potrzebne dla Kern_info
#include // potrzebne do makr
int __init hw_init (void)
printk (kern_info "hello świat \ n");
powrót 0;

void __exit hw_exit (void)
printk (kern_info "pa pa World \ n");

Module_license („gpl”);
module_init (hw_init);
module_exit (hw_exit);

Makefile

OBJ-M: = Hello.o
Wszystko:
Make -c/lib/modules/$ (shell uname -r)/build m = $ (PWD) moduły
czysty:
Make -c/lib/modules/$ (shell uname -r)/build m = $ (PWD) Clean

Utwórz folder o nazwie Witam a następnie umieść Witam.C I Makefile w środku tego. Otworzyć terminal aplikacja i katalog zmian na Hello. Teraz uruchom polecenie robić a jeśli się powiedzie, powinien wygenerować załadowany plik modułu jądra Witam.Ko.

Po uruchomieniu wykonaj, jeśli otrzymasz wyjście Make: Nic do zrobienia dla „wszystkich”. Następnie upewnij się, że w karcie Makefile wprowadziłeś (bez spacji) przed wykonaniem -c. Jeśli Make zakończy się powodzeniem, powinieneś uzyskać dane wyjściowe, jak pokazano poniżej.

Make [1]: Wprowadzanie katalogu '/usr/src/linux-headers-3.13.0-128-generalny '
CC [M]/Home/John/Desktop/Hello/Hello.o
Moduły budowlane, etap 2.
Modpost 1 moduły
CC/Home/John/Desktop/Hello/Hello.mod.o
Ld [m]/home/John/Desktop/mvs/pers/kern/hello/hello.Ko
Make [1]: opuszczenie katalogu '/usr/src/linux-headers-3.13.0-128-generalny '

Teraz przetestujmy moduł, ładując go do jądra. Do ładowania i rozładunku modułów jądra musimy mieć uprawnienia Superuser. Użyj następującego polecenia, aby załadować moduł jądra do jądra.

sudo insmod hello.Ko

Aby zobaczyć wiadomość PrintK, musisz sprawdzić dziennik jądra, aby sprawdzić dziennik jądra, użyj następującego polecenia.

Dmesg

To polecenie wyprowadzi komunikaty dziennika jądra, na końcu powinieneś zobaczyć, że nasza wiadomość Witaj świecie wydrukowane.

Aby rozładować moduł, użyj następującego polecenia.

sudo rmmod hello

Aby zobaczyć wiadomość printk, użyj ponownie polecenia DMESG i w dzienniku jądra możesz zobaczyć naszą wiadomość Do widzenia świata.

Teraz pozwól nam zrozumieć kod źródłowy.

Witam.C

Aby rozpocząć pisanie sterownika jądra, możesz użyć dowolnego edytora lub IDE Twojego wyboru, ale najczęściej programiści jądra wolą używać vi redaktor.

Każdy moduł jądra powinien zawierać plik nagłówka Linux/moduł.H ma to deklaracje i makra dla funkcji jądra, takich jak module_init I module_exit itp. Dwie najbardziej niezbędne funkcje dla sterownika jądra to funkcje module_init i module_exit. Funkcja, której wskaźnik jest przekazywany do module_init, zostanie wykonana po załadowaniu modułu do jądra, a funkcja, której wskaźnik jest przekazywany do modułu_exit, zostanie wywołana po rozładowaniu lub usunięciu modułu z jądra.

Wewnątrz jądra do debugowania i drukowania dziennika używamy Prink funkcja podobna do funkcji printf, której używamy w aplikacji. Możesz użyć makr, takich jak Kern_Info, Kern_ERR itp.

Jeśli piszemy sterownik, aby porozmawiać z określonym sprzętem, funkcja init powinna mieć kod do zainicjowania sprzętu, zanim zaczniemy go używać, a funkcja wyjścia powinna mieć kod do czyszczenia zasobów (pamięć dynamiczna itp.) Zanim wyjdziemy z jądra.

Tutaj w tym przykładzie drukujemy po prostu wiadomości debugowania w funkcjach init i wyjścia.

Makefile

Aby zbudować moduł jądra, musimy napisać Makefile, który będzie prowadził robić narzędzie Jak skompilować moduł. Składnia OBJ-M jest używany do informowania makefile jądra, że ​​sterownik musi zostać skompilowany jako moduł za pomocą określonego pliku obiektowego. Kiedy po prostu uruchomisz polecenie robić wtedy kontrola dochodzi do Wszystko: sekcja Makefile i jeśli uruchomisz polecenie Wyczyść się Następnie kontrola trafia do czysty: Sekcja Makefile. Z tego Makefile faktycznie uruchamiamy w katalogu źródła jądra za pomocą opcji -C. Upewnij się, że masz w systemie zainstalowany katalog źródłowy jądra. Tutaj w tym przykładzie użyliśmy polecenia Uname -r Aby znaleźć bieżącą wersję jądra systemu Linux.

Użyliśmy opcji M = $ (PWD), aby wskazać w makefile jądra, że ​​źródło sterownika jest w obecnym katalogu roboczym i określamy słowo moduły powiedzieć Kernel Makefile, aby po prostu budował moduły i nie budować kompletnego kodu źródłowego jądra. W czysty: Sekcja Makefile mówimy Kernel Makefile do czyszczenia plików obiektów wygenerowanych w celu zbudowania tego modułu.

To jeśli zaczniesz kompilacja i uruchamia swój pierwszy moduł jądra.