3.3. 让控制台工作

3.3.1. 强制内核以我们的方式启动

一旦我们发现内核确实在启动,但是控制台没有打印任何内容,就到了开始的时候了。首先,我们强制内核使用指定的串口配置启动,在我们的例子中是9600n1,并且不允许任何命令行选项或启动时间考虑等。

首先要去的地方是drivers/char/tty_io.c,到console_init()。此函数确定启动时的控制台配置。这是一小部分
memset(, 0, sizeof(struct termios));
memcpy(tty_std_termios.c_cc, INIT_C_CC, NCCS);
tty_std_termios.c_iflag = ICRNL | IGNPAR;
tty_std_termios.c_oflag = OPOST | ONLCR;
tty_std_termios.c_cflag = CLOCAL | B9600 | CS8 | CREAD;
tty_std_termios.c_cflag &= ~(CRTSCTS);
tty_std_termios.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
tty_std_termios.c_iflag = ICRNL | IXON;
tty_std_termios.c_oflag = OPOST | ONLCR;
tty_std_termios.c_cflag = B38400 | CS8 | CREAD | HUPCL;
tty_std_termios.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
我们尝试的第一件(幼稚的)事情是按照我们想要的方式配置控制台。当然,这对我们没有太大帮助 ;-)

失望但没有气馁,我们记得我们还没有引导加载程序,并且我们不确定是否有任何选项传递给内核。“也许内核收到了命令行的一些垃圾?”我们(再次,天真地)认为。所以我们尝试阻止内核解析命令行选项,并手动插入我们的命令行。这对我们没有太大帮助 ;-)

3.3.2. 非标准硬件 - 就是拒绝!

那时,我们没有控制台,但我们有时间。所以我们更深入地研究了控制台问题。查看drivers/char/serial.c,我们遇到了serial_console_setup()。此函数除了解析命令行选项外,还通过直接写入来配置串口。我们的硬件人员认为现在是时候告诉我们,我们的串口不是标准的。用于流量控制的线路未连接。我们决定注释掉以下行,该行将 RTS 和 DTR 线路设置为高电平,因为我们根本没有这些线路。
serial_out(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
当然,这对我们没有太大帮助 :-( 这里学到的教训是检查,检查,检查你的硬件!。定制板可能不是标准的,如果您了解它,移植会更快。

3.3.3. 让光明出现:计算波特率

最后,我们决定检查波特率。当 Linux 说 9600 时,它是否意味着我们认为的意思?可能不是,因为我们不知道它是如何计算该值的。我们注意到文件include/asm-ppc/pmppc_serial.h(将 pmppc 替换为您的板名称)包含一个定义BAUDBASE,稍后用于与串口相关的所有内容。它是使用板的本地总线频率、总线时钟与系统时钟比率等计算出来的。这似乎是错误的,因此我们检查了我们在板上运行的 vxWorks 系统中的基本波特率,并将其更改为
/*
 * system clock = 33Mhz, serial clock = system clock / 4
 * the following must hold: (divisor * BaudRate) == (System clock / 64)
 */
#define BASE_BAUD (33000000 / 4 / 16)
快速编译,然后重新启动后,我们通过串口看到了正在启动的内核。成功!