使用dmesg打印所有日志( 二 )


这里的链表结构应该是如下这样的:

使用dmesg打印所有日志

文章插图
搜索这个注册函数的调用,发现使用了这个注册函数,可以看到le的name正是""
s3c24xx_serial_initconsole// 驱动相关,先看看是不是有硬件驱动struct platform_device *dev = s3c24xx_uart_devs[0];//注册consoleregister_console(&s3c24xx_serial_console);static struct console s3c24xx_serial_console ={.name= S3C24XX_SERIAL_NAME,.device= uart_console_device,.flags= CON_PRINTBUFFER,.index= -1,.write= s3c24xx_serial_console_write,.setup= s3c24xx_serial_console_setup};#define S3C24XX_SERIAL_NAME "ttySAC"#define S3C24XX_SERIAL_MAJOR204#define S3C24XX_SERIAL_MINOR64
write
可以在这个结构体里面发现write函数操作了实际的硬件,也就是write是是实际的写硬件函数
s3c24xx_serial_console_write>uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar);>wr_regb(cons_uart, S3C2410_UTXH, ch);
asmlinkage int printk(const char *fmt, ...){va_start(args, fmt);r = vprintk(fmt, args);va_end(args);}
这个函数最后会查找这个链表来进行打印处理,通过判断是否输出到硬件
vprintk(const char *fmt, va_list args){// 解析数据到一个buf/* Emit the output into the temporary buffer */printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args);//对buf 进行特殊处理printk_buf,填充到 log_buffor (p = printk_buf; *p; p++){//如果没有 形如 <数字> 的开头,自动补上 也就是<4>,提取这个lev//如果有,同样提取这个levemit_log_char(c)}if (cpu_online(smp_processor_id()) || have_callable_console()) {//have_callable_console 遍历 console_drivers// > for (con = console_drivers; con; con = con->next)// 这个链表就是register_console 中注册的了console_may_schedule = 0;// 打印输出release_console_sem();{....}}}
先将数据输出到,实际的输出到硬件会去判断一个打印级别,不论是否到达打印级别,都可以使用dmesg显示这个[]
release_console_sem(){// 静态全局变量_con_start = con_start;_log_end = log_end;call_console_drivers(_con_start, _log_end);{// 提取打印等级msg_level = LOG_BUF(cur_index + 1) - '0';_call_console_drivers(start_print, cur_index, msg_level);{// lev < 设置的log lev,则打印if ((msg_log_level < console_loglevel || ignore_loglevel) && console_drivers && start != end){//遍历console驱动链表,判断是否有write函数,如果有,执行write函数__call_console_drivers(start, end);{for (con = console_drivers; con; con = con->next){if ((con->flags & CON_ENABLED) && con->write...)con->write(con, &LOG_BUF(start), end - start);}}}}}}
【使用dmesg打印所有日志】打印级别
我们在里面使用的是s中判断if< ,也就是说默认的级别就是,也就是默认小于才打印
#define console_loglevel (console_printk[0]) ==7
可以使用cat /proc/sys//查看是不是这个,这个值就是数组[4]
# cat /proc/sys/kernel/printk7417
具体相关的定义在这里,可以使用\linux\.h查看
int console_printk[4] = {//=7DEFAULT_CONSOLE_LOGLEVEL,/* console_loglevel *///=4DEFAULT_MESSAGE_LOGLEVEL,/* default_message_loglevel *///=1MINIMUM_CONSOLE_LOGLEVEL,/* minimum_console_loglevel *///=7DEFAULT_CONSOLE_LOGLEVEL,/* default_console_loglevel */};/* printk's without a loglevel use this.. */#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING *//* We show everything that is MORE important than this.. */#define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */#define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */#defineKERN_EMERG"<0>"// 系统崩溃#defineKERN_ALERT"<1>"//必须紧急处理#defineKERN_CRIT"<2>"// 临界条件,严重的硬软件错误#defineKERN_ERR"