Systemy operacyjne 2 - Projekt pierwszy


Jesień 2006

Sterownik urządzenia



1. Schowek Minimum (22p). Sterownik urządzenia znakowego tylko do zapisu pełniący funkcję “schowka”, w którym można zapisać fragment pamięci ekranu. Sterownik interpretuje wysyłane do niego strumienie bajtów jako komendy. Rozpoznawane powinny być następujące rodzaje komend (każdy argument komendy to jeden bajt):

- <KOPIUJ, XLT, YLT, XRB, YRB> - kopiuje do schowka prostokątny fragment ekranu o lewym górnym rogu określonym przez argumenty XLT YLT i prawym dolnym rogu określonym przez pola XRB, YRB>.

- <WKLEJ, XLT, YLT> - wkleja fragment ekranu zapisany w schowku, umieszczając jego lewy górny róg w miejscu określonym przez argumenty XLT, YLT.

- <WYCZYSC> - czyści schowek (zwalnia pamięć).

W przypadku napotkania błędnego numeru polecenia, lub błędnych parametrów np X>80 należy zwrócić kod błędu. Operacja write jest nieblokująca a polecenie wykonywane jest dopiera po wysłaniu wszystkich argumentów, co oznacza że proces może poprawnie wykonać polecenie WKLEJ wykonując trzy jedno bajtowe zapisy.

Dodatkowo (7p) gdy jeden proces rozpocznie polecenie, a nie przekaże wszystkich parametrów, wszystkie procesy usiłujące wykonać operację write są blokowane do momentu (a) przesłania pozostałych parametrów przez proces rozpoczynający operację albo (b) zamknięcia przez ten proces pliku, co oznacza anulowanie polecenia.

(8p) Każdy użytkownik ma osobny schowek. (sterownik rozpoznaje uid użytkownika i wykonuje operacje na jego indywidualnym schowku)

 

2. Komórki ekranowe. (Minimum 22p) Sterownik urządzenia, zaimplementowany jako moduł jądra, w którym operacje odczytu i zapisu dotyczą komórki konsoli (ekranu) o współrzędnych 0<=X<=79, 0<=Y<=24. Operacja read zwraca znak znajdujący się w danej chwili w komórce, a operacja write zmienia ten znak. Współrzędne komórki możemy zmienić oraz odczytać przy pomocy odpowiednich komend ioctl. Jeżeli operacja read/write dotyczy więcej niż jednego bajtu, to proces jest usypiany na co najmniej t ms przed kolejnym odczytem komórki. Czas uśpienia t (początkowo 100ms) możemy również zmieniać i odczytywać przy pomocy wywołania ioctl, niezależnie dla operacji write oraz read. Sterownik może obsługiwać maksymalnie do 255 niezależnych urządzeń o kolejnych numerach podrzędnych (liczba urządzeń jest przekazywana jako parametr modułu), z których każde obsługuję inną komórkę. Próba związania dwóch różnych urządzeń podrzędnych z tą samą komórką jest błędem (nie dotyczy to inicjalizacji).

Dodatkowo (10p) Możliwość przełączenia przy pomocy ioctl w tryb, w którym zapisy są buforowane. W trybie tym operacja write powoduje przepisanie danych do wewnętrznego bufora, i natychmiastowy powrót. W przypadku przepełnienia bufora następuje jego re-alokacja (przydział nowego , o dwukrotnie większej długości, bez utraty danych). Następnie dane z zaprogramowanym odstępem t przepisywane są na ekran (Np. przy wykorzystaniu timerów jądra). Możliwość przełączenia przy pomocy ioctl do standardowego trybu zapisu.

(5p) Obsługa wywołania select dla zapisów, przy czym brak gotowości jest zgłaszany (lub następuje uśpienie procesu), gdy zapis prowadziłby do przepełnienia bufora. [Wymaga samodzielnej pracy z literaturą np. książka Linux Kernel – jądro systemu].

3. Wielki bufor - plik (Minimum 22p.) Bufor w pamięci (koncepcyjnie tablica bajtów) traktowany jako plik. Odczyt z bufora odbywa się od offsetu równego bieżącemu wskaźnikowi pliku i przesuwa ten wskaźnik o liczbę bajtów. Gdy osiągnięty zostanie koniec bufora, traktowany jest jak koniec pliku (obcięcie liczby zapisanych bajtów). Zapis przesuwa również wskaźnik o pewną liczbę bajtów, a ponadto może powiększyć bufor, gdy w trakcie zapisu przekroczymy koniec. Moduł jądra obsługuje cztery numery podrzędne odpowiadające czterem niezależnym buforom. Możliwość otwarcia tego samego bufora przez różne procesy lub wielokrotnie przez ten sam proces.

Dodatkowo (7p) Możliwość wywołania ioctl zmieniającego rozmiar bufora, przy czym zmniejszenie bufora możliwe jest tylko wtedy gdy wszystkie wskaźniki bieżącej pozycji pliku (wszystkich plików otwartych z danym urządzeniem) związane z tym buforem „zmieszczą” się w nowym buforze. W przeciwnym wypadku zwracany jest kod błędu.

(8p) Implementacja operacji mmap [Patrz literatura oraz przyszłe wykłady na temat zarządzania pamięcią (np. funkcja remap_page_range) ], pozwalającej na odwzorowanie bufora lub jego fragmentu w przestrzeni adresowej użytkownika. Może to wymagać innej organizacji bufora, niż ciągły blok pamięci.



UWAGA: Należy napisać programy pozwalające przetestować działanie sterownika (nie interaktywne, a pobierające odpowiednie argumenty z linii poleceń). Programy te należy wywołać z przykładowego skryptu shella. Brak rzetelnych programów i skryptów testujących skutkuje karą o maksymalnej wysokości -5p.

PONADTO: Zalecamy analizę kodu prawdziwych sterowników w jądrze.



Opracowali:
Wojciech Kwedlo i Krzysztof Bandurski.