程序14-28 linux/include/linux/tty.h
1 /*
2 * 'tty.h' defines some structures used by tty_io.c and some defines.
3 *
4 * NOTE! Don't touch this without checking that nothing in rs_io.s or
5 * con_io.s breaks. Some constants are hardwired into the system (mainly
6 * offsets into 'tty_queue'
7 */
/*
* 'tty.h'中定义了tty_io.c程序使用的某些结构和其他一些定义。
*
* 注意!在修改这里的定义时,一定要检查rs_io.s或con_io.s程序中不会出现问题。
* 在系统中有些常量是直接写在程序中的(主要是一些tty_queue中的偏移值)。
*/
8
9 #ifndef _TTY_H
10 #define _TTY_H
11
12 #define MAX_CONSOLES 8 // 最大虚拟控制台数量。
13 #define NR_SERIALS 2 // 串行终端数量。
14 #define NR_PTYS 4 // 伪终端数量。
15
16 extern int NR_CONSOLES; // 虚拟控制台数量。
17
18 #include <termios.h> // 终端输入输出函数头文件。主要定义控制异步通信口的终端接口。
19
20 #define TTY_BUF_SIZE 1024 // tty缓冲区(缓冲队列)大小。
21
// tty字符缓冲队列数据结构。用于tty_struc结构中的读、写和辅助(规范)缓冲队列。
22 struct tty_queue {
23 unsigned long data; // 队列缓冲区中含有字符行数值(不是当前字符数)。
// 对于串口终端,则存放串行端口地址。
24 unsigned long head; // 缓冲区中数据头指针。
25 unsigned long tail; // 缓冲区中数据尾指针。
26 struct task_struct * proc_list; // 等待本队列的进程列表。
27 char buf[TTY_BUF_SIZE]; // 队列的缓冲区。
28 };
29
30 #define IS_A_CONSOLE(min) (((min) & 0xC0) == 0x00) // 是一个控制终端。
31 #define IS_A_SERIAL(min) (((min) & 0xC0) == 0x40) // 是一个串行终端。
32 #define IS_A_PTY(min) ((min) & 0x80) // 是一个伪终端。
33 #define IS_A_PTY_MASTER(min) (((min) & 0xC0) == 0x80) // 是一个主伪终端。
34 #define IS_A_PTY_SLAVE(min) (((min) & 0xC0) == 0xC0) // 是一个辅伪终端。
35 #define PTY_OTHER(min) ((min) ^ 0x40) // 其他伪终端。
36
// 以下定义了tty等待队列中缓冲区操作宏函数。(tail在前,head在后,参见tty_io.c的图)。
// a缓冲区指针前移1字节,若已超出缓冲区右侧,则指针循环。
37 #define INC(a) ((a) = ((a)+1) & (TTY_BUF_SIZE-1))
// a缓冲区指针后退1字节,并循环。
38 #define DEC(a) ((a) = ((a)-1) & (TTY_BUF_SIZE-1))
// 清空指定队列的缓冲区。
39 #define EMPTY(a) ((a)->head == (a)->tail)
// 缓冲区还可存放字符的长度(空闲区长度)。
40 #define LEFT(a) (((a)->tail-(a)->head-1)&(TTY_BUF_SIZE-1))
// 缓冲区中最后一个位置。
41 #define LAST(a) ((a)->buf[(TTY_BUF_SIZE-1)&((a)->head-1)])
// 缓冲区满(如果为1的话)。
42 #define FULL(a) (!LEFT(a))
// 缓冲区中已存放字符的长度(字符数)。
43 #define CHARS(a) (((a)->head-(a)->tail)&(TTY_BUF_SIZE-1))
// 从queue队列项缓冲区中取一字符(从tail处,并且tail+=1)。
44 #define GETCH(queue,c) \
45 (void)({c=(queue)->buf[(queue)->tail];INC((queue)->tail);})
// 往queue队列项缓冲区中放置一字符(在head处,并且head+=1)。
46 #define PUTCH(c,queue) \
47 (void)({(queue)->buf[(queue)->head]=(c);INC((queue)->head);})
48
// 判断终端键盘字符类型。
49 #define INTR_CHAR(tty) ((tty)->termios.c_cc[VINTR]) // 中断符。发中断信号SIGINT。
50 #define QUIT_CHAR(tty) ((tty)->termios.c_cc[VQUIT]) // 退出符。发退出信号SIGQUIT。
51 #define ERASE_CHAR(tty) ((tty)->termios.c_cc[VERASE]) // 削除符。擦除一个字符。
52 #define KILL_CHAR(tty) ((tty)->termios.c_cc[VKILL]) // 删除行。删除一行字符。
53 #define EOF_CHAR(tty) ((tty)->termios.c_cc[VEOF]) // 文件结束符。
54 #define START_CHAR(tty) ((tty)->termios.c_cc[VSTART]) // 开始符。恢复输出。
55 #define STOP_CHAR(tty) ((tty)->termios.c_cc[VSTOP]) // 停止符。停止输出。
56 #define SUSPEND_CHAR(tty) ((tty)->termios.c_cc[VSUSP]) // 挂起符。发挂起信号SIGTSTP。
57
// tty数据结构。
58 struct tty_struct {
59 struct termios termios; // 终端io属性和控制字符数据结构。
60 int pgrp; // 所属进程组。
61 int session; // 会话号。
62 int stopped; // 停止标志。
63 void (*write)(struct tty_struct * tty); // tty写函数指针。
64 struct tty_queue *read_q; // tty读队列。
65 struct tty_queue *write_q; // tty写队列。
66 struct tty_queue *secondary; // tty辅助队列(存放规范模式字符序列),
67 }; // 可称为规范(熟)模式队列。
68
69 extern struct tty_struct tty_table[]; // tty结构数组。
70 extern int fg_console; // 前台控制台号。
71
// 根据终端类型在tty_table[] 中取对应终端号nr的tty 结构指针。第73行后半部分用于
// 根据子设备号dev在tty_table[]表中选择对应的tty结构。如果dev = 0,表示正在使用
// 前台终端,因此直接使用终端号fg_console 作为 tty_table[] 项索引取 tty结构。如果
// dev大于0,那么就要分两种情况考虑:① dev 是虚拟终端号;② dev 是串行终端号或者
// 伪终端号。对于虚拟终端其tty结构在 tty_table[]中索引项是 dev-1(0 -- 63)。对于
// 其它类型终端,则它们的 tty结构索引项就是 dev。例如,如果dev = 64,表示是一个串
// 行终端1,则其tty 结构就是 ttb_table[dev]。 如果dev = 1,则对应终端的tty结构是
// tty_table[0]。参见tty_io.c程序第70 -- 73行。
72 #define TTY_TABLE(nr) \
73 (tty_table + ((nr) ? (((nr) < 64)? (nr)-1:(nr)) : fg_console))
74
// 这里给出了终端termios结构中可更改的特殊字符数组c_cc[]的初始值。该termios结构
// 定义在include/termios.h中。POSIX.1定义了11个特殊字符,但是Linux系统还另外定
// 义了SVR4使用的6个特殊字符。如果定义了_POSIX_VDISABLE(\0),那么当某一项值等
// 于_POSIX_VDISABLE的值时,表示禁止使用相应的特殊字符。[8进制值]
75 /* intr=^C quit=^| erase=del kill=^U
76 eof=^D vtime=\0 vmin=\1 sxtc=\0
77 start=^Q stop=^S susp=^Z eol=\0
78 reprint=^R discard=^U werase=^W lnext=^V
79 eol2=\0
80 */
/* 中断intr=^C 退出quit=^| 删除erase=del 终止kill=^U
* 文件结束eof=^D vtime=\0 vmin=\1 sxtc=\0
* 开始start=^Q 停止stop=^S 挂起susp=^Z 行结束eol=\0
* 重显reprint=^R 丢弃discard=^U werase=^W lnext=^V
* 行结束eol2=\0
*/
81 #define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
82
83 void rs_init(void); // 异步串行通信初始化。(kernel/chr_drv/serial.c)
84 void con_init(void); // 控制终端初始化。 (kernel/chr_drv/console.c)
85 void tty_init(void); // tty初始化。 (kernel/chr_drv/tty_io.c)
86
87 int tty_read(unsigned c, char * buf, int n); // (kernel/chr_drv/tty_io.c)
88 int tty_write(unsigned c, char * buf, int n); // (kernel/chr_drv/tty_io.c)
89
90 void con_write(struct tty_struct * tty); // (kernel/chr_drv/console.c)
91 void rs_write(struct tty_struct * tty); // (kernel/chr_drv/serial.c)
92 void mpty_write(struct tty_struct * tty); // (kernel/chr_drv/pty.c)
93 void spty_write(struct tty_struct * tty); // (kernel/chr_drv/pty.c)
94
95 void copy_to_cooked(struct tty_struct * tty); // (kernel/chr_drv/tty_io.c)
96
97 void update_screen(void); // (kernel/chr_drv/console.c)
98
99 #endif
100