3.1. 使用 print_str() 进行调试

正如上一章所述,机器开始启动,但没有任何反应。至少,我们看不到任何反应。屏幕是空白的,没有出现任何内核消息。此时,您必须问自己,它真的在启动吗?

由于控制台无法启动,而且 ICE 很快就停止工作了,我们别无选择。我们必须以某种方式进行调试,而最古老的方法在这里很有用 - 向屏幕打印内容。显然,我们无法使用printk(),所以我们编写了一个短函数,将字符直接推送到串口。我们使用了上一节中显示的启动过程"映射",并在沿途插入了一些打印语句。这帮助我们了解我们完成了哪个阶段,以及在哪里遇到问题。以下代码通过轮询串口并等待其空闲,将单个字符打印到串口。
                                 /* tx holding reg empty or tx    */
#define LSR_THREMPTY 0x20        /* fifo is empty (in fifo mode ) */
#define THR_REG      0x00        /* Transmit holding reg */
#define LSR_REG      0x05        /* Line status reg */
#define COM1_ADDRESS 0xFF600300  /* == replace with your UART address */

void print_char (char ch) {
	volatile  unsigned char status = 0;
	/* wait until txempty */
	while ((status & LSR_THREMPTY ) == 0)
		status = *((volatile unsigned char *)(COM1_ADDRESS + LSR_REG));

	*((volatile unsigned char *)(COM1_ADDRESS + THR_REG)) = ch;
}

Note

有一个更好的代码可以直接打印到串口,但是它有点复杂。您可以在 arch/ppc/boot/common/misc-common.c 中找到它,使用puts()或者putc().