Linux内核调试技术之printk(2)

printk vprintk vscnprintf //先把输出信息放入临时BUFFER      // Copy the output into log_buf.     // 把临时BUFFER里的数据稍作处理,再写入log_buf     // 比如printk("abc")会得到"<4>abc", 再写入log_buf     // 可以用dmesg命令把log_buf里的数据打印出来重现内核的输出信息 // 调用硬件的write函数输出 release_console_sem call_console_drivers
          //从log_buf得到数据,算出打印级别 _call_console_drivers
if ((msg_log_level < console_loglevel)//如果级别足够则打印 __call_console_drivers con->write //con是console_drivers链表中的项,对用具体的输出函数 在drives/serial/s3c2410.c中查看

在该函数中注册一个console结构体

static void s3c24xx_serial_console_write(struct console *co, const char *s, unsigned int count) { uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar); }

串口输出函数,会调用s3c24xx_serial_console_putchar函数

static int s3c24xx_serial_initconsole(void) { ........................... register_console(&s3c24xx_serial_console); return 0; }
static struct console s3c24xx_serial_console =
{
.name = S3C24XX_SERIAL_NAME,//这个宏被定义为:TTYSAC
.device = uart_console_device, //init进程,用户程序打开/dev/console的时候会调用
.flags = CON_PRINTBUFFER,//打印还没有初始化化console前保存在log_buf里面的数据
.index = -1,//选择那个串口,由uboot中的命令决定
.write = s3c24xx_serial_console_write,//控制台输出函数
.setup = s3c24xx_serial_console_setup //串口设置函数
};
 

这个函数和硬件相关,读取寄存器,看数据是否被发送完成,最后将数据一个字节一个字节的写入寄存器,s3c2440的串口控制器会自动把数据发送出去

static void s3c24xx_serial_console_putchar(struct uart_port *port, int ch) { unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON); while (!s3c24xx_serial_console_txrdy(port, ufcon)) barrier(); wr_regb(cons_uart, S3C2410_UTXH, ch); }

uboot的console=ttySAC0如果在linux中被识别出来是串口0的,在/kernel/printk.c中有一下代码,

__setup("console=", console_setup); static int __init console_setup(char *str)
{
........
  add_preferred_console(name, idx, options);
}
 

内核开始执行时,会发现“console=...”的命令行参数时候,就会调用console_setup函数进行数据解析,对于命令行参数"console=ttySAC0",会解析出:设备名(name)为ttySAC,索引index为0,这些信息被保存在类型为console_cmdline、名称为console_cmdline的全局数组中(注意:数组名和数组的类型相同)

在后面的register_console(&s3c24xx_serial_console);的时候,会将s3c24xx_serial_console结构和console_cmdline数组中的设备进行比较。

①解析出来的name为S3C24XX_SERIAL_NAME 既“ttySAC”,而console_cmdline中的命令中的name也为“ttySAC”

②s3c24xx_serial_console结构体中的索引index为-1,表示使用命令行参数“console=ttySAC0”中的索引,index =  0

如果还想了解uboot的console=ttySAC0如果在linux中被识别出来是串口0的,可以看《嵌入式Linux开发完全手册》Page 365  PDF下载见

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/ee832d5ec77619ca034b71bbcaa0dd6a.html