TTY 结构体¶
struct tty_struct
在首次打开 TTY 设备时由 TTY 层分配,并在最后一次关闭后释放。TTY 层将此结构传递给大多数 struct tty_operation 的钩子。tty_struct 的成员记录在底部的 TTY 结构体参考中。
初始化¶
-
void tty_init_termios(struct tty_struct *tty)¶
用于 termios 设置的助手
参数
struct tty_struct *tty
要设置的 tty
描述
初始化此 tty 的 termios 结构。这目前在 tty_mutex
下运行,因此我们可以放松对排序的要求。
名称¶
-
const char *tty_name(const struct tty_struct *tty)¶
返回 tty 命名
参数
const struct tty_struct *tty
tty 结构
描述
将 tty 结构转换为名称。该名称反映了内核命名策略,如果正在使用 udev,则可能不反映用户空间
锁定:无
引用计数¶
-
struct tty_struct *tty_kref_get(struct tty_struct *tty)¶
获取 tty 引用
参数
struct tty_struct *tty
tty 设备
返回
tty 对象的新引用
描述
锁定:调用者必须持有足够的锁/计数,以确保其现有引用不会消失。
-
void tty_kref_put(struct tty_struct *tty)¶
释放 tty kref
参数
struct tty_struct *tty
tty 设备
描述
释放对 tty 设备的引用,如果需要,让 kref 层为我们销毁该对象。
安装¶
-
int tty_standard_install(struct tty_driver *driver, struct tty_struct *tty)¶
通常的 tty->ops->install
参数
struct tty_driver *driver
tty 的驱动程序
struct tty_struct *tty
tty
描述
如果 driver 重写 tty->ops->install,它仍然可以调用此函数来执行标准安装操作。
读取 & 写入¶
-
int tty_put_char(struct tty_struct *tty, u8 ch)¶
向 tty 写入一个字符
参数
struct tty_struct *tty
tty
u8 ch
要写入的字符
描述
如果存在,使用提供的 tty->ops->put_char() 方法向 tty 写入一个字节。
注意
驱动程序层中的特定 put_char 操作可能很快就会消失。不要直接调用它,使用此方法
返回
成功输出的字符数。
启动 & 停止¶
-
void stop_tty(struct tty_struct *tty)¶
传播流控制
参数
struct tty_struct *tty
要停止的 tty
描述
对驱动程序执行流控制。可以在已停止的设备上调用,并且不会重新调用 tty_driver->stop()
方法。
此功能由线路规程用于停止传入流量以及驱动程序使用。因此,可以从任何上下文调用它,可以在 tty atomic_write_lock
下,但并非总是如此。
- 锁定
flow.lock
-
void start_tty(struct tty_struct *tty)¶
传播流控制
参数
struct tty_struct *tty
要启动的 tty
描述
尽可能启动已停止的 tty。如果 tty 之前已停止,现在正在启动,则会调用 tty_driver->start()
方法,并且唤醒线路规程。
- 锁定
flow.lock
唤醒¶
-
void tty_wakeup(struct tty_struct *tty)¶
请求更多数据
参数
struct tty_struct *tty
终端
描述
tty唤醒的内部和外部辅助函数。此函数通知线路规程(如果存在),驱动程序已准备好接收更多输出数据。
挂断¶
-
void tty_hangup(struct tty_struct *tty)¶
触发挂断事件
参数
struct tty_struct *tty
要挂断的tty
描述
tty 上发生了载波丢失(虚拟或其他)。安排在此事件后运行挂断序列。
-
void tty_vhangup(struct tty_struct *tty)¶
处理虚拟挂断
参数
struct tty_struct *tty
要挂断的tty
描述
用户已通过系统调用请求挂断终端。我们同步执行此操作,以便在系统调用返回时进程完成。为了安全起见,该保证是必要的。
参数
struct file *filp
tty的文件指针
返回
如果tty受到虚拟挂断或载波丢失的影响,则为真
杂项¶
-
int tty_do_resize(struct tty_struct *tty, struct winsize *ws)¶
调整大小事件
参数
struct tty_struct *tty
正在调整大小的tty
struct winsize *ws
新的尺寸
描述
更新termios变量并发送必要的信号以正确执行终端大小调整。
TTY结构标志¶
这些位用于tty_struct.flags
字段中。
为了使中断不会弄乱队列,copy_to_cooked 必须相对于自身是原子的,tty->write 也必须是原子的。因此,您必须使用内联函数 set_bit()
和 clear_bit()
来使事情成为原子的。
- TTY_THROTTLED
驱动程序输入受到限制。lcsic 应该调用
tty_driver.unthrottle()
以便在准备好处理更多数据时(在阈值最小值时)恢复接收。- TTY_IO_ERROR
如果设置,会导致随后在 tty 上的所有用户空间读/写调用失败,返回 -
EIO
。(也可能没有 ldisc。)- TTY_OTHER_CLOSED
设备是 pty,另一端已关闭。
- TTY_EXCLUSIVE
独占打开模式(单个打开器)。
- TTY_DO_WRITE_WAKEUP
如果设置,会导致驱动程序调用
tty_ldisc_ops.write_wakeup()
方法,以便在它可以接受更多要传输的数据时恢复传输。- TTY_LDISC_OPEN
指示行规程已打开。仅用于调试目的。
- TTY_PTY_LOCK
pty 代码私有的标志,用于实现
TIOCSPTLCK
/TIOCGPTLCK
逻辑。- TTY_NO_WRITE_SPLIT
防止驱动程序将写入分成较小的块(将写入边界保留到驱动程序)。
- TTY_HUPPED
TTY 已挂断。这在
tty_driver.hangup()
之后设置。- TTY_HUPPING
TTY 正在挂断以中止潜在的读取器。
- TTY_LDISC_CHANGING
此 TTY 的行规程正在更改。设置此项时,I/O 不应阻塞。使用 tty_io_nonblock() 进行检查。
- TTY_LDISC_HALTED
此 TTY 的行规程已停止。不应将任何工作排队到此 ldisc。
TTY 结构参考¶
-
struct tty_struct¶
打开时与 tty 关联的状态
定义:
struct tty_struct {
struct kref kref;
int index;
struct device *dev;
struct tty_driver *driver;
struct tty_port *port;
const struct tty_operations *ops;
struct tty_ldisc *ldisc;
struct ld_semaphore ldisc_sem;
struct mutex atomic_write_lock;
struct mutex legacy_mutex;
struct mutex throttle_mutex;
struct rw_semaphore termios_rwsem;
struct mutex winsize_mutex;
struct ktermios termios, termios_locked;
char name[64];
unsigned long flags;
int count;
unsigned int receive_room;
struct winsize winsize;
struct {
spinlock_t lock;
bool stopped;
bool tco_stopped;
} flow;
struct {
struct pid *pgrp;
struct pid *session;
spinlock_t lock;
unsigned char pktstatus;
bool packet;
} ctrl;
bool hw_stopped;
bool closing;
int flow_change;
struct tty_struct *link;
struct fasync_struct *fasync;
wait_queue_head_t write_wait;
wait_queue_head_t read_wait;
struct work_struct hangup_work;
void *disc_data;
void *driver_data;
spinlock_t files_lock;
int write_cnt;
u8 *write_buf;
struct list_head tty_files;
#define N_TTY_BUF_SIZE 4096;
struct work_struct SAK_work;
};
成员
kref
通过
tty_kref_get()
和tty_kref_put()
进行引用计数,达到零时会释放该结构index
此 tty 的索引(例如,构造像 tty12 这样的名称)
dev
类设备或
NULL
(例如,ptys、serdev)driver
操作此 tty 的
struct tty_driver
port
此设备的持久存储(即
struct tty_port
)ops
此 tty 的 driver 的
struct tty_operations
(打开、关闭等)ldisc
此 tty 的当前行规程(默认为 n_tty)
ldisc_sem
保护行规程更改(ldisc)--锁定 tty 而不是 pty
atomic_write_lock
防止并发写入,即锁定 write_cnt、write_buf 和类似内容
legacy_mutex
历史遗留(BKL -> BTM -> legacy_mutex),保护对此 tty 的多个操作
throttle_mutex
防止并发
tty_throttle_safe()
和tty_unthrottle_safe()
(但不是tty_unthrottle()
)termios_rwsem
保护 termios 和 termios_locked
winsize_mutex
保护 winsize
termios
当前 tty 的 termios,从/复制到 driver.termios
termios_locked
锁定的 termios(通过
TIOCGLCKTRMIOS
和TIOCSLCKTRMIOS
ioctl)name
由
tty_line_name()
构造的 tty 的名称(例如 ttyS3)flags
TTY_THROTTLED
、TTY_IO_ERROR
... 的按位或count
打开进程的计数,达到零时会取消此 tty 的所有工作并丢弃一个 kref(但不释放此 tty)
receive_room
允许馈送到 ldisc 而不会丢失的字节数
winsize
终端“窗口”的大小(参见 winsize_mutex)
flow
分组在一起的流设置
flow.lock
flow 成员的锁
flow.stopped
通过
stop_tty()
/start_tty()
停止/启动的 ttyflow.tco_stopped
tty 通过
TCOOFF
/TCOON
ioctl 停止/启动(它优先于 flow.stopped)ctrl
控制设置组合在一起
ctrl.pgrp
此 tty 的进程组 (setpgrp(2))
ctrl.session
此 tty 的会话 (setsid(2))。写入受 ctrl.lock 和 legacy_mutex 的保护,读取者必须至少使用其中一个。
ctrl.lock
ctrl 成员的锁
ctrl.pktstatus
数据包模式状态(
TIOCPKT_
常量的按位或)ctrl.packet
数据包模式已启用
hw_stopped
不受 tty 层控制,由 driver 控制用于 CTS 处理
closing
在关闭期间设置时,n_tty 仅处理 START 和 STOP 字符
flow_change
控制节流的行为,请参阅
tty_throttle_safe()
和tty_unthrottle_safe()
link
链接到另一个 pty (master -> slave 和反之亦然)
fasync
O_ASYNC
的状态 (用于SIGIO
);由 fasync_helper() 管理write_wait
并发写入者在此队列中等待,直到允许他们写入
read_wait
读取者在此队列中等待数据
hangup_work
通常是执行挂起的工作 (do_tty_hangup());在释放 tty 时,(重新)用于
release_one_tty()
disc_data
指向 ldisc 私有数据的指针(例如,指向
struct n_tty_data
)driver_data
指向 driver 私有数据的指针(例如,
struct uart_state
)files_lock
保护 tty_files 列表
write_cnt
在
tty_write()
中写入到 write_buf 的字节计数write_buf
在
tty_write()
期间用于复制用户数据的临时缓冲区tty_files
此 tty 的(重新)打开者列表(即,链接的
struct tty_file_private
)SAK_work
如果 tty 有挂起的 do_SAK,它会在此处排队
描述
tty 打开时与 tty 关联的所有状态。tty 设备的持久存储在此处引用为 port,并在 struct tty_port
中进行了说明。