Sterownik urządzenia HardDoom
Budowanie, instalacja
Potrzebujemy źródła Linuxa w katalogu linux/
(można podsymlinkować).
make
insmod harddoom.ko
Możliwe, że jeszcze będziemy chcieli móc pisać/czytać do urządzenia:
chmod a+rw /dev/doom0
Opis plików w rozwiązaniu
harddoom_main.c
Punkt wejściowy do modułu. Inicjalizuje sterowniki urządzenia znakowego i PCI.
pci.c
Definiujemy sterownik urządzenia PCI. W operacji probe
włączymy urządzenie
HardDoom i stworzymyy odpowiadające mu urządzenie znakowe /dev/doomX
.
Podczas inicjalizacji urządzenia również rejestrujemy handler przerwań, który
pomoże nam w synchronizacji z urządzeniem.
char.c
Implementacja urządzenia znakowego. Rejestrujemy je w sysfs. Definiujemy ioctle
dostępne na /dev/doomX
.
surface.c
Implementacja buforów ramek, operacji które na nich wykonujemy, i pomocniczych struktur (buforów tekstur, etc.).
harddoomdev.c
Implementacja wrapperów na operacje, które możemy wykonywać na urządzeniu.
Między innymi operacja start_dev
, która uruchamia urządzenie, ładując
mikrokod.
private_data.h
Definicje struktur, które trzymamy jako dane prywatny sterowników lub inode'ów odpowiadających buforom.
util.h
Makra do obsługi błędów.
Szczegóły implementacji
Korzystamy z FIFO, nie bloku poleceń.
Synchronizacja
- Korzystamy z algorytmu ze wskazówek do znajdowania wolnego miejsca w FIFO.
- Zakładamy lock na urządzenie gdy wysyłamy polecenia. Nie czekamy na ich zakończenie.
- W operacji
read
na buforze ramki, czekamy na zakończenie rysowania poprzezPING_SYNC
. Kładziemy się na semaforze, handler przerwania nas obudzi gdy przyjdziePONG_SYNC
. Aby zapewnić, że w locie jest tylko jedenPING_SYNC
, przed wysłaniem bierzemy mutexa przeznaczonego do tego celu.
Bezpieczeństwo, obsługa błędów
- Staramy się zwracać sensowne kody błędów, na tyle na ile pozwala nam wybór kodów w jądrze.
- Wszystkie dane, na które dostajemy wskaźnik z przestrzeni użytkownika
kopiujemy do naszej pamięci operacją
copy_from_user
.