/*** early_console_setup - setup debugging console** Consoles started here require little enough setup that we can start using* them very early in the boot process, either right after the machine* vector initialization, or even before if the drivers can detect their hw.** Returns non-zero if a console couldn't be setup.* This function is developed based on* early_console_setup function as defined in arch/ia64/kernel/setup.c* 這個注釋里寫的很清楚,在設備驅動執行之前,為了調試錯誤的需要我們* 需要在啟動的最初就初始化控制臺*/
void __init early_console_setup(unsigned long base, struct clk *clk)
{
#ifdef CONFIG_SERIAL_IMX_CONSOLE
mxc_early_serial_console_init(base, clk);
#endif
}
這里調用mxc_early_serial_console_init(base, clk);
android\kernel_imx\drivers\tty\serial、mxc_uart_early.c
int __init mxc_early_serial_console_init(unsigned long base, struct clk *clk)
{
mxc_early_device.clk = clk;
mxc_early_device.port.mapbase = base;register_console(&mxc_early_uart_console);
return 0;
}
/*!* This function is called to write the console messages through the UART port.** @param co the console structure* @param s the log message to be written to the UART* @param count length of the message*/
void __init early_mxcuart_console_write(struct console *co, const char *s,
u_int count)
{
struct uart_port *port = &mxc_early_device.port;
unsigned int status, oldcr1, oldcr2, oldcr3, cr2, cr3;/*
* First save the control registers and then disable the interrupts
*/
oldcr1 = readl(port->membase + MXC_UARTUCR1); //讀取當前三個串口控制寄存器的值
oldcr2 = readl(port->membase + MXC_UARTUCR2);
oldcr3 = readl(port->membase + MXC_UARTUCR3);
cr2 =oldcr2 & ~(MXC_UARTUCR2_ATEN | MXC_UARTUCR2_RTSEN | //初始化串口寄存器數值MXC_UARTUCR2_ESCI);
cr3 =oldcr3 & ~(MXC_UARTUCR3_DCD | MXC_UARTUCR3_RI |MXC_UARTUCR3_DTRDEN);
writel(MXC_UARTUCR1_UARTEN, port->membase + MXC_UARTUCR1); //使能串口
writel(cr2, port->membase + MXC_UARTUCR2); //配置寄存器
writel(cr3, port->membase + MXC_UARTUCR3);/* Transmit string */
uart_console_write(port, s, count, mxcuart_console_write_char); //發送數據/*
* Finally, wait for the transmitter to become empty等待發送完成
*/
do {
status = readl(port->membase + MXC_UARTUSR2);
} while (!(status & MXC_UARTUSR2_TXDC));/*
* Restore the control registers
*/
writel(oldcr1, port->membase + MXC_UARTUCR1);//恢復串口寄存器數值
writel(oldcr2, port->membase + MXC_UARTUCR2);
writel(oldcr3, port->membase + MXC_UARTUCR3);
}