linux的启动阶段分为内核加载、根文件系统加载,在内核加载时可以通过命令行支持多个控制台,而在根文件系统里可以在/etc/inittab表里添加多个控制台,这样就实现了多控制台监控。
具体步骤如下:
1. 内核命令行配置双控制台,如ttyS0、ttyUSB0,注意命令行里这两个设备的顺序,ttyUSB0的优先级要比ttyS0高。
Kernel command line: root=/dev/mtdblock4 rootfstype=cramfs rootflags=inband-tags console=ttyS0 console=ttyUSB0,115200n8 rdinit=/sbin/init mem=32M quiet
2. 在第1.执行完后,将会在根文件系统内部创建/dev/console设备,假如终端在上电时就在usb口上插入了usb-232,那么从内核跨度到根文件系统时/dev/console指向的是ttyUSB0设备,反之指向的是/dev/ttyS0。这里会引发另外一个问题,usb-232在usb口上热插拔,将导致/dev/ttyUSBx的序号增加,如ttyUSB0、ttyUSB1、ttyUSB2...所以需要修改驱动,
内核驱动路径:drivers\usb\serial\usb-serial.c
static struct usb_serial *get_free_serial(struct usb_serial *serial,
int num_ports, unsigned int *minor)
{
unsigned int i, j;
int good_spot;
dev_dbg(&serial->interface->dev, "%s %d\n", __func__, num_ports);
*minor = 0;
mutex_lock(&table_lock);
//-------------------------------------------------------
//这里修改主要是为了实现USB作为控制台使用,强制
//serial_table[0]=NULL,为了防止usb-232热插拔,
//导致设备号增加(如/dev/ttyUSB0-->拔插-->/dev/ttyUSB1...),
//-------------------------------------------------------
serial_table[0] = NULL;
for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
...
3.修改根文件系统文件/etc/inittab,需要屏蔽console作为控制台来引导/bin/sh,原因是如果上电时就插入了usb-232,那么内核将选择ttyUSB0控制台传送给根文件系统,创建1号进程init,以此来加载我们的应用程序...如果此时拔掉了usb-232,那么/dev/ttyUSB0设备将被释放,init=1号进程将退出,导致根文件系统崩溃,所以要改为下面两种方式来启动控制台,这样两个控制台可以同时工作
#console::respawn:-/bin/sh
ttyS0::respawn:-/bin/sh
ttyUSB0::respawn:-/bin/sh
4. 在第3.步执行两个控制台后最终都会调用/bin/sh,通过busybox查看ash.c源码知道最终会调用/etc/profile文件,而我要运行的应用程序却在/etc/profile文件里启动,这里两个控制台将启动两个应用程序,很明显这不满足要求,所以需要修改profile文件,即在根文件系统里需确定ttyS0、ttyUSB0哪个为主,哪个为辅,由于ttyS0设备是一直存在,ttyUSB0设备插入时才可以生成,所以这里以ttyS0为主,即只在控制台为ttyS0才加载应用程序,其它控制台都跳过,修改profile文件如下
if [ $(tty) = "/dev/ttyS0" ]; then
#加载运行的应用程序
fi
5. 实测,ok!