printk会把数据放在内核的1个缓冲区里面,另外一路把信息从硬件上输出出来,当我们想查看之前的信息可以用dmesg命令打印出缓冲区里面的信息。dmesg命令打印出来的信息来自/proc/kmsg

dmesglog怎么导出 dmesg输出到文件_驱动程序

proc是虚拟的文件系统

系统启动的时候

dmesglog怎么导出 dmesg输出到文件_环形缓冲_02

里面有mount -a这里a代表把所有的文件系统都挂接上去。

dmesglog怎么导出 dmesg输出到文件_文件系统_03

所有的文件系统在文件fstab中,如把proc文件系统挂载在/proc目录下

dmesglog怎么导出 dmesg输出到文件_驱动程序_04

查看挂载的文件系统

dmesglog怎么导出 dmesg输出到文件_dmesglog怎么导出_05

虚拟文件系统proc里面的文件是内核帮我们生成的,属性是读

dmesglog怎么导出 dmesg输出到文件_dmesglog怎么导出_06

可以用 cat /proc/kmsg来查看内核输出信息,每行信息前面都会有打印级别

dmesglog怎么导出 dmesg输出到文件_环形缓冲_07


再使用cat /proc/kmsg就没有输出信息了,可能是里面读写机制的问题

驱动程序里面都是用printk,假设内核的打印信息非常多,驱动程序把打印信息单独抽出来存在某个地方,不想跟别的东西混杂在一起,可以仿照构造/proc/kmsg文件,驱动程序的信息打印到另外一个buffer里面


printk的信息分两路,一路存在log_buf里面(可以通过 /proc/kmsg文件),一路打印出来。仿照:定义1个buf如mulog_buf,生成1个文件/proc/mymsg,读文件/proc/mymsg吧信息打印出来,驱动myprintk把信息存在log_buf

dmesglog怎么导出 dmesg输出到文件_文件系统_08

在内核的fs目录下子目录有proc,里面有proc的各种操作函数

分析proc_misc.c 入口函数

如果配置了CONFIG_PRINTK,create_proc_entry函数创建proc目录里面的1个条目,第1个参数名字是kmsg,第2个参数是属性(只读),第3个参数是parent,表示proc这个根目录里面。创建完后这个条目的file_operation结构体。当应用程序打开/proc/kmsg后,open,read,write时用到结构体proc_kmsg_operation(file_operation)的open,read,write

dmesglog怎么导出 dmesg输出到文件_环形缓冲_09

搜索别的程序调用create_proc_entry函数,看包含什么文件。

环形缓冲区

buf数组

dmesglog怎么导出 dmesg输出到文件_环形缓冲_10

printk.c里面

头跟尾一样(读写位置)为空时休眠,当里面有数据时,头尾不相等就会唤醒

dmesglog怎么导出 dmesg输出到文件_驱动程序_11

唤醒后从环形缓冲区读取数据,然后通过调用_put_user返回给用户

dmesglog怎么导出 dmesg输出到文件_文件系统_12