一、内核是如何确定printk的输出设备:
以IMX6为例:
u-boot命令行:console=ttymxc0,它使得prink的信息从串口0输出。
在kernel/printk.c中有如下代码:
__setup("console=", console_setup);
内核开始执行时,发现形如"console="的命令行参数时,会调用console_setup函数进行解析。对应命令行参数console=ttymxc0,它会解析出:name为ttymxc,index为0,这些信息被保存在类型为console_cmdline、名称为console_cmdline的全局数组中。
控制台设备的入口函数,调用register_console注册控制台,将mxc_early_uart_console结构与console_cmdline数组中的设备进行比较,发现名字相同,向console_driver链表注册一个console。
例如:drivers/tty/serial/mxc_uart_early.c文件里的函数mxc_early_serial_console_init:
register_console(&mxc_early_uart_console);
mxc_early_uart_console的定义:
static struct console mxc_early_uart_console __initdata = {
.name = "ttymxc",
.write = early_mxcuart_console_write,
.setup = mxc_early_uart_setup,
.flags = CON_PRINTBUFFER | CON_BOOT,
.index = -1,
};
printk函数调用流程:
printk->
vprintk->
emit_log_char //把要打印的数据写入log_buf,log_buf的内容可以通过dmesg命令输出
release_console_sem->
call_console_drivers->
_call_console_drivers->
__call_console_drivers->
con->write //这个就对应上面的early_mxcuart_console_write,从而最终输出到串口上。
二、printk的使用:
第一种:
//#define DBG_PRINTK printk
#define DBG_PRINTK(x...)
DBG_PRINTK("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
第二种:
printk(KERN_DEBUG"%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
(1)修改printk 打印级别,使其大于KERN_DEBUG:
echo 10 > /proc/sys/kernel/printk
查看打印级别:
cat /proc/sys/kernel/printk
(2)u-boot命令行参数里:loglevel=xx