Teletypewriter (TTY) layer takes care of all those serial devices. Including the virtual ones like pseudoterminal (PTY).
There are several major TTY structures. Every TTY device in a system has a
struct tty_port. These devices are maintained by a TTY driver
struct tty_driver. This structure describes the driver but also
contains a reference to operations which could be performed on the TTYs. It is
struct tty_operations. Then, upon open, a
struct tty_struct is allocated and
lives until the final close. During this time, several callbacks from
tty_operations are invoked by the TTY layer.
Every character received by the kernel (both from devices and users) is passed
through a preselected TTY Line Discipline (in
short ldisc; in C,
struct tty_ldisc_ops). Its task is to transform characters
as defined by a particular ldisc or by user too. The default one is n_tty,
implementing echoes, signal handling, jobs control, special characters
processing, and more. The transformed characters are passed further to
user/device, depending on the source.
In-detail description of the named TTY structures is in separate documents:
- TTY Driver and TTY Operations
- TTY Port
- TTY Struct
- TTY Line Discipline
- TTY Buffer
- TTY Internals
Writing TTY Driver¶
Before one starts writing a TTY driver, they must consider Serial and USB Serial layers first. Drivers for serial devices can often use one of these specific layers to implement a serial driver. Only special devices should be handled directly by the TTY Layer. If you are about to write such a driver, read on.
A typical sequence a TTY driver performs is as follows:
Allocate and register a TTY driver (module init)
Create and register TTY devices as they are probed (probe function)
Handle TTY operations and events like interrupts (TTY core invokes the former, the device the latter)
Remove devices as they are going away (remove function)
Unregister and free the TTY driver (module exit)