m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff

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

  1. Korzystamy z algorytmu ze wskazówek do znajdowania wolnego miejsca w FIFO.
  2. Zakładamy lock na urządzenie gdy wysyłamy polecenia. Nie czekamy na ich zakończenie.
  3. W operacji read na buforze ramki, czekamy na zakończenie rysowania poprzez PING_SYNC. Kładziemy się na semaforze, handler przerwania nas obudzi gdy przyjdzie PONG_SYNC. Aby zapewnić, że w locie jest tylko jeden PING_SYNC, przed wysłaniem bierzemy mutexa przeznaczonego do tego celu.

Bezpieczeństwo, obsługa błędów

  1. Staramy się zwracać sensowne kody błędów, na tyle na ile pozwala nam wybór kodów w jądrze.
  2. Wszystkie dane, na które dostajemy wskaźnik z przestrzeni użytkownika kopiujemy do naszej pamięci operacją copy_from_user.