这里的链表结构应该是如下这样的:
文章插图
搜索这个注册函数的调用,发现使用了这个注册函数,可以看到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"
- pycharm使用笔记2-远程连接
- 传真和打印有区别吗,传真与打印机有什么区别
- 优酷iPad版怎么退出登录,如何使用ipad mii
- 使用 Electron-Vue 开发的桌面应用
- 闲鱼为什么显示服务器忙,使用ServerStatus
- 优启通本地模式使用教程,使用优启通u盘怎样安装wi10系统
- 庞统都做了哪些贡献庞统怎么使用连环计的
- 使用shuttle实现bytom上跨链资产交换
- Ubuntu中OpenCV的安装及使用示例
- 使用<stdarg.h>实现可变参数,av_list的使用