/*** 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* 這個(gè)注釋里寫(xiě)的很清楚,在設(shè)備驅(qū)動(dòng)執(zhí)行之前,為了調(diào)試錯(cuò)誤的需要我們* 需要在啟動(dòng)的最初就初始化控制臺(tái)*/
void __init early_console_setup(unsigned long base, struct clk *clk)
{
#ifdef CONFIG_SERIAL_IMX_CONSOLE
mxc_early_serial_console_init(base, clk);
#endif
}
這里調(diào)用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); //讀取當(dāng)前三個(gè)串口控制寄存器的值
oldcr2 = readl(port->membase + MXC_UARTUCR2);
oldcr3 = readl(port->membase + MXC_UARTUCR3);
cr2 =oldcr2 & ~(MXC_UARTUCR2_ATEN | MXC_UARTUCR2_RTSEN | //初始化串口寄存器數(shù)值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); //發(fā)送數(shù)據(jù)/*
* Finally, wait for the transmitter to become empty等待發(fā)送完成
*/
do {
status = readl(port->membase + MXC_UARTUSR2);
} while (!(status & MXC_UARTUSR2_TXDC));/*
* Restore the control registers
*/
writel(oldcr1, port->membase + MXC_UARTUCR1);//恢復(fù)串口寄存器數(shù)值
writel(oldcr2, port->membase + MXC_UARTUCR2);
writel(oldcr3, port->membase + MXC_UARTUCR3);
}