Do tematu: Podsystem wej¶cia-wyj¶cia
Do tematu: Struktury danych
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. |
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 |
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.
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). |