Do tematu: Podsystem wej¶cia-wyj¶cia

Do tematu: Struktury danych

Struktura tty_driver

Struktura tty_driver opisuje sterownik urz±dzenia terminalowego. Inicjalizowana jest podczas rozpoczêcia pracy systemu operacyjnego i w przeciwieñstwie do struktury tty_struct istnieje statycznie. Struktura ta jest zwi±zana nie z pojedynczym urz±dzeniem, ale z typem (podtypem) urz±dzenia. Do obs³ugi takich samych urz±dzeñ, nawet je¶li jest ich kilkadziesi±t, s³u¿y tylko jedna struktura tty_driver. Je¶li jakie¶ urz±dzenie terminalowe jest zarejestrowane w tablicy urz±dzeñ znakowych chrdevs, to opisuj±ca sterownik tego urz±dzenia struktura tty_driver znajduje siê na dwukierunkowej li¶cie tty_drivers.

Struktura tty_driver jest zdefiniowana w pliku /include/linux/tty_driver.h.

typ nazwa pola opis
int magic Liczba magiczna
const char* name Nazwa urz±dzenia.

Przyk³adowe warto¶ci tego pola to: "tty", "console", "pty", "ttyp". Je¶li np. sterownik opisywany przez strukturê tty_driver jest sterownikiem czê¶ci podrzêdnej pseudoterminala, to pole name jest równe "ttyp".

int name_base Warto¶ci± pola name_base jest liczba definiuj±ca przesuniêcie wykorzystywane przy okre¶laniu nazwy urz±dzenia. Zazwyczaj w systemie Linux mo¿e byæ obs³ugiwanych jednocze¶nie wiele urz±dzeñ o tym samym numerze g³ównym. Wówczas pole name nie wystarcza do okre¶lenia jednoznacznej nazwy urz±dzenia. Dlatego napis, zapamiêtany w polu name, jest konkatenowany z liczb±, która jest wyliczana w nastêpuj±cy sposób:

numer drugorzêdny urz±dzenia - minor_start + name_base

W wyniku powy¿szych dzia³añ powstaj± takie nazwy jak tty4, tty24, itp. Przewa¿nie warto¶ci± pola name_base jest zero. Wyj±tek stanowi± konsole. Dla konsol pole name_base jest równe jeden. Jest to zwi±zane z faktem, ¿e konsola o numerze drugorzêdnym zero oznacza bie¿±c± konsolê. Zatem nazwy konsol zaczynaj± siê od tty1, a nie tty0.

short major Numer g³ówny urz±dzenia
short minor_start Najmniejszy numer drugorzêdny urz±dzenia o numerze g³ównym major. Od tego numeru rozpoczynaj± siê numery drugorzêdne urz±dzenia danego typu. Obecnie przyjmuje nastêpuj±ce warto¶ci:

1 dla konsol

64 dla terminali

128 dla pseudoterminali nadrzêdnych

192 dla pseudoterminali podrzêdnych

short num Liczba urz±dzeñ danego typu, które mog± byæ jednocze¶nie obs³ugiwane przez system operacyjny Linux. Dla konsol i pseudoterminali pole to przyjmuje nastêpuj±ce warto¶ci:

MAX_NR_CONSOLES 63

NR_PTYS 256

Obecnie jednak, warto¶æ NR_PTYS jest przepisywana (zmieniana na 64) . System mo¿e obs³ugiwaæ 64 pseudoterminale nadrzêdne i 64 pseudoterminale podrzêdne.

short type Typ sterownika
short subtype Podtyp sterownika
struct termios init_termios Pocz±tkowe ustawienia parametrów pracy urz±dzenia terminalowego.
int flags Flagi
int* refcount Licznik wska¼ników w tablicy table, które s± ró¿ne od NULL.

Zmienne typu tty_struct, opisuj±ce urz±dzenia terminalowe, s± tworzone i niszczone dynamicznie. Pocz±tkow± warto¶ci± wszystkich wska¼ników w tablicy table jest NULL. Podczas inicjalizacji urz±dzenia przydzielana jest pamiêæ na zmienn± typu tty_struct. Wska¼nik do tej zmiennej jest m.in. umieszczany w tablicy table. Wówczas zwiêkszany jest licznik *refcount. Gdy urz±dzenie jest zwalniane, licznik *refcount jest zmniejszany, a w tablicy table odpowiedni wska¼nik przyjmuje warto¶æ NULL.

Licznik *refcount jest potrzebny, poniewa¿ jeden sterownik mo¿e obs³ugiwaæ wiele urz±dzeñ. Je¶li warto¶æ licznika *refcount jest równa zero, to sterownik nie obs³uguje ¿adnych urz±dzeñ i mo¿na go np. wyrejestrowaæ z tablicy chrdevs[]. Dok³adniej: z tablicy chrdevs[] wyrejestrowywane jest urz±dzenie o numerze g³ównym równym polu major.

struct tty_driver* other Je¶li struktura tty_driver opisuje sterownik czê¶ci podrzêdnej (nadrzêdnej) pseudoterminala, to other jest wska¼nikiem na strukturê opisuj±c± sterownik czê¶ci nadrzêdnej (podrzêdnej) tego pseudoterminala.
struct tty_struct** table Tablica wska¼ników do struktur tty_struct, które opisuj± aktualnie otwarte urz±dzenia terminalowe, obs³ugiwane przez dany sterownik. Rozmiarem tablicy table jest liczba numerów drugorzêdnych zdefiniowanych dla urz±dzenia. Urz±dzeniu o logicznym numerze drugorzêdnym i, odpowiada struktura *table[i]. Logicznym numerem drugorzêdnym urz±dzenia jest liczba:

drugorzêdny numer urz±dzenia - minor_start

struct termios** termios Tablica wska¼ników do struktur termios. Jej rozmiar jest taki jak rozmiar tablicy table. Je¶li urz±dzenie terminalowe, o logicznym numerze drugorzêdnym i, jest otwarte, to table[i]->termios = termios[i].
struct termios** termios_locked Tablica wska¼ników do struktur termios. Jej rozmiar jest taki jak rozmiar tablicy table. Je¶li urz±dzenie terminalowe, o logicznym numerze drugorzêdnym i, jest otwarte, to table[i]->termios_locked = termios_locked[i].
int (*open)(struct tty_struct * tty, struct file * filp) Funkcja open jest wo³ana, gdy urz±dzenie terminalowe, obs³ugiwane przez dany sterownik, jest otwierane. Je¶li nie jest zdefiniowana, próba otwarcia koñczy siê b³êdem ENODEV (ang. error no device).
void (*close)(struct tty_struct * tty, struct file * filp) Funkcja close jest wo³ana, gdy urz±dzenie jest zamykane.
int (*write)(struct tty_struct * tty, int from_user, const unsigned char *buf, int count) Funkcja write musi byæ zdefiniowana, tzn. dla ka¿dego sterownika write jest ró¿ne od NULL. Wo³ana jest przez j±dro, aby zapisaæ sekwencjê znaków do urz±dzenia. Znaki mog± pochodziæ z przestrzeni adresowej u¿ytkownika lub j±dra. Funkcja zwraca liczbê zapisanych znaków.
void (*put_char)(struct tty_struct *tty, unsigned char ch) Funkcja put_char jest wo³ana przez j±dro, aby zapisaæ pojedynczy znak do urz±dzenia terminalowego. Znak ten nie jest jednak fizycznie przesy³any do urz±dzenia, ale tylko umieszczany w kolejce wyj¶ciowej sterownika. Je¶li w kolejce tej nie ma miejsca, znak jest ignorowany.
void (*flush_chars)(struct tty_struct *tty) Funkcja flush_chars jest wo³ana przez j±dro po zapisaniu znaków do urz±dzenia terminalowego za pomoc± funkcji put_char. Zazwyczaj funkcja ta zapisuje dane do portów.
int (*write_room)(struct tty_struct *tty) Funkcja write_room zwraca liczbê znaków, które sterownik mo¿e w danym momencie przyj±æ do kolejki wyj¶ciowej.
int (*chars_in_buffer)(struct tty_struct *tty) Funkcja chars_in_buffer zwraca liczbê znaków, znajduj±cych siê w kolejce wyj¶ciowej sterownika.
int (*ioctl)(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) Przy pomocy funkcji ioctl procesy mog± sterowaæ prac± urz±dzenia. Wiele sterowników definiuje komendy, specyficzne dla urz±dzenia, które obs³uguj±. Je¶li komenda (cmd) nie zosta³a przez sterownik rozpoznana, zwracany jest b³±d ENOIOCTLCMD (ang. error no ioctl command).
void (*set_termios)(struct tty_struct *tty, struct termios * old) Funkcja set_termios jest wo³ana, aby poinformowaæ sterownik o zmianie ustawieñ w strukturze termios. Struktura ta definiuje parametry pracy urz±dzenia obs³ugiwanego przez ten sterownik.
void (*throttle)(struct tty_struct * tty) Funkcja throttle jest wo³ana, gdy wej¶ciowa kolejka znaków dyscypliny linii jest bliska przepe³nienia. Funkcja ta jest zwi±zana z flag± TTY_THROTTLED.
void (*unthrottle)(struct tty_struct * tty) Funkcja unthrottle jest wo³ana, aby powiadomiæ sterownik, ¿e dyscyplina linii mo¿e ju¿ przyjmowaæ kolejne znaki. Funkcja ta równie¿ jest zwi±zana z flag± TTY_THROTTLED.
void (*stop)(struct tty_struct *tty) Funkcja stop powiadamia sterownik, ¿e powinien przestaæ wysy³aæ znaki do obs³ugiwanego urz±dzenia.
void (*start)(struct tty_struct *tty) Funkcja start powiadamia sterownik, ¿e powinien wznowiæ wysy³anie znaków do urz±dzenia.
void (*hangup)(struct tty_struct *tty) Funkcja hangup informuje sterownik o tym, ¿e obs³ugiwane przez niego urz±dzenie powinno zostaæ zawieszone.
void (*flush_buffer)(struct tty_struct *tty) Funkcja flush_buffer usuwa znaki z bufora wyj¶ciowego sterownika. W przeciwieñstwie do funkcji flush_chars, nie zapisuje niczego do portów. St±d wniosek, ¿e s³owo flush u¿yte jest tutaj w znaczeniu discard (pozbyæ siê, odrzuciæ).
void (*set_ldisc)(struct tty_struct *tty) Funkcja set_ldisc powiadamia sterownik o zmianie parametrów pracy urz±dzenia. Jest wo³ana, je¶li urz±dzeniu zosta³a przydzielona nowa dyscyplina linii.
struct tty_driver * next Wska¼nik do nastêpnej struktury tty_driver na li¶cie tty_drivers.
struct tty_driver * prev Wska¼nik do poprzedniej struktury tty_driver na li¶cie tty_drivers.

Pocz±tek pliku

Typy

flaga kod opis
TTY_DRIVER_TYPE_SYSTEM 0x0001 Obecnie nieu¿ywany
TTY_DRIVER_TYPE_CONSOLE 0x0002 Sterownik konsoli
TTY_DRIVER_TYPE_SERIAL 0x0003 Sterownik ³±cza szeregowego
TTY_DRIVER_TYPE_PTY 0x0004 Sterownik pseudoterminala
TTY_DRIVER_TYPE_SCC 0x0005 Sterownik urz±dzeñ SCC

Pocz±tek pliku

Podtypy

flaga kod opis
SYSTEM_TYPE_TTY 0x0001 Obecnie nieu¿ywany
SYSTEM_TYPE_CONSOLE 0x0002 Obecnie nieu¿ywany
PTY_TYPE_MASTER 0x0001 Sterownik pseudoterminala nadrzêdnego
PTY_TYPE_SLAVE 0x0002 Sterownik pseudoterminala podrzêdnego

W podprogramach obs³ugi urz±dzeñ mog± byæ zdefiniowane dodatkowe podtypy, ¶ci¶le zwi±zane z rodzajem urz±dzenia.

Pocz±tek pliku

Flagi

flaga kod opis
TTY_DRIVER_INSTALLED 0x0001 Ustawiona oznacza, ¿e sterownik jest zarejestrowany, tzn. struktura tty_driver opisuj±ca ten sterownik znajduje siê na li¶cie tty_drivers oraz w tablicy chrdevs[] jest zarejestrowane urz±dzenie o numerze g³ównym równym numerowi g³ównemu urz±dzenia obs³ugiwanego przez ten sterownik. Obecnie flaga ta u¿ywana jest wy³±cznie w funkcji tty_register_driver() znajduj±cej siê w pliku /drivers/char/tty_io.c.
TTY_DRIVER_RESET_TERMIOS 0x0002 Ustawienie flagi tej oznacza, ¿e podczas od³±czania terminala (funkcja do_tty_hangup() w pliku tty_io.c) zostanie nadana inicjalna warto¶æ polu termios w strukturze tty_struct. Ponadto, przy zamykaniu terminala (funkcja release_dev() w pliku tty_io.c) przez ostatni pod³±czony do niego proces, flaga ta, ustawiona, spowoduje zwolnienie pamiêci zajmowanej przez strukturê termios tego terminala.
TTY_DRIVER_REAL_RAW 0x0004 Ustawienie flagi tej oznacza, ¿e urz±dzenie pracuje w trybie surowym oraz dodatkowo: pomijane lub akceptowane s± znaki, które spowodowa³y b³±d kontroli parzysto¶ci, a tak¿e nie jest sygnalizowane nadej¶cie znaku przerywaj±cego (VINTR).


Autor: Maciej Kaczmarek