程序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.scon_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[] 中取对应终端号nrtty 结构指针。第73行后半部分用于

    // 根据子设备号devtty_table[]表中选择对应的tty结构。如果dev = 0,表示正在使用

    // 前台终端,因此直接使用终端号fg_console 作为 tty_table[] 项索引取 tty结构。如果

    // dev大于0,那么就要分两种情况考虑:① dev 是虚拟终端号;② dev 是串行终端号或者

    // 伪终端号。对于虚拟终端其tty结构在 tty_table[]中索引项是 dev-10 -- 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