通用控制台和串口控制台

时间:2022-01-12 11:11:18
通用控制台和串口控制台 控制台的思想 过去,计算机是一个庞然大物,附带着十几个终端设备。其中一个终端具有“系统控制台”的特殊作用。它是唯一用于系统恢复的单用户模式终端,也是唯一接受系统错误消息的终端。当今的计算机都配有键盘和显示设备,不再带有多个文本终端。于是“系统控制台”就由本地键盘和监视器担任。而当计算机主机没有连接显示硬件设备时,一般就由串口设备担任“系统控制台”。把串口设备的电缆插入就可以得到诊断信息和登陆提示字。把控制台当作控制终端是合适的。通过它作为输入输出通道从而可以启动一个根shell并发送内核消息则是完全不同的机制。我们关注的是消息是如何传送给系统控制台设备的。 系统预设的控制台 当在计算机中安装了文本模式的gnu/linux系统时,系统预设的控制台就是当前的虚拟终端。 传送消息到控制台的机制是由printk函数实现的。该函数使用vsprintf(lib/vsprintf.c)产生消息串,把它放入内核消息的环形缓冲区中,然后将消息传给所有活动的console设备,只要该消息的优先级数字小于console_loglevel。 变量console_loglevel用于选择何种消息可以输出到系统控制台上。预设值是DEFAUL_CONSOLE_LOGLEVEL。系统管理员可以通过写/proc/sys/kernel/printk 该变其值。 这些优先级数值用宏KERN_ERROR,KERN_DEBUG等定义为0-7级。 if (msg_level < console_loglevel && console_drivers) { struct console *c = console_drivers; while(c) { if ((c->flags & CON_ENABLED) && c->write) c->write(c, msg, p - msg + line_feed); c = c->next; } } 大多数linux配置中只有一个控制台注册,它对应于虚拟终端,代码在consol.c中。实际的消息打印是由vt_console_print执行的。看一下它的源码就会发现它并不总是把消息打印到前台虚拟终端,但可以配置为打印消息到一个虚拟终端上。如果变量kmsg_redirect非0,其值就是那个选来接受内核消息的虚拟终端的号。该变量可以通过调用ioctl(TIOCLINUX)(一个linux定义的tty的ioctl命令)作用到一个虚拟终端的文件描述符上。 如果正在运行的是带有串口的标准pc,可以通过传递一个命令行选项console=给内核以选择一个串口作为控制台。文件Documentation/serial-console.txt清楚地描述了所需要的整个设备和操作细节。 声明和选择一个控制台 为了声明一个新的控制台设备,内核代码应首先包含,这个头文件定义了struct console结构和几个flags.随后就可以调用register_console把控制台插入到活动控制台的数据结构表格中 例如以下是串口声明和注册过程: static struct console sercons = { name: "ttyS", write: serial_console_write, device: serial_console_device, wait_key: serial_console_wait_key, setup: serial_console_setup, flags: CON_PRINTBUFFER, index: -1, }; void __init serial_console_init(void) { register_console(&sercons); } 写一个控制台驱动程序 console的初始化console结构中有几个成员只是为了使console的初始化和配置过程简单.name和setup成员用于命令行解析系统启动时,为每个"console="内核命令行参数调用console_setup (在kernel/printk.c中).该函数保存所有命令行的命令到一个数组中.当以后调用register_console注册一个console时,如果发现命令数组中的名字和console的名字域匹配,则以命令行中相应的option为参数调用console的setup初始化函数.使得console符合命令行的要求. console标志CON_ENABLE 指明该控制台设备是否是默认启动的,只有启动的控制台才接受内核消息,如果内核命令行选中了 这个console,并且console的setup函数调用成功,系统自动为该console设置此标志. 进一步,此标志为首次注册的console设立.这就是串口或并口控制台在自己的console结构中默认都没有 设置这一标志的原因.默认情况下串,并口不是作为控制台使用的.除非用户在命令行指定串,并口作为 控制台或者没有虚拟终端设备作为默认控制台.CON_PRINTBUFFER 此标志请求将缓冲的内核消息输出到这个控制台上.例如串,并口设置此标志就可显示所有内核启动消息: 当注册串,并口为console时设置了此标志,内核随即把缓存的消息输出到它们上面.CON_CONSDEV 控制台请求成为优先的设备,优先的设备总是被放入console表的第一项. ----------------------------控制台数据结构表struct console { char name[8]; //设备名用于解析命令行选项console= void (*write)(struct console *,const char *,unsigned); int (*read)(struct console*,const char*,unsigned); struct tty_driver *(*device)(struct console, void (*unblank)(void);int*); //当前作为console的tty设备 int (*setup)(struct console*,char*); 初始化串口函数 short falgs; short index; //设备数组中为console设备的索引号 int cflag; struct console *next; } console_drivers是表头指针(不是console_driver)