Linux dmesg缓冲区

本文介绍了如何修改Linux内核的printk日志等级,通过调整/proc/sys/kernel/printk文件内容,控制打印到控制台的日志级别,以过滤不必要的调试信息。同时,讲解了dmesg环形缓冲区大小的调整方法,通过修改CONFIG_LOG_BUF_SHIFT宏定义来改变缓冲区容量,从而影响内核信息的存储能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  printk 将内核信息输出到内核信息缓冲区中,内核缓冲区在 kernel/printk/printk.c 中定义,内核信息缓冲区是一个环形缓冲区(Ring Buffer),如果dmesg消息过多,会将之前的消息冲掉。

static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);

1. 修改printk打印等级

调试内核模块时候,若调试信息太多可以通过修改/proc/sys/kernel/printk文件内容来控制。

查看当前printk打印消息的log等级:

$  cat /proc/sys/kernel/printk
 1       4       1       7
#|       |       |       |-默认的控制台日志级别:控制台日志级别的缺省值
#|       |       |       
#|       |       |--最低的控制台日志级别:控制台日志级别可被设置的最小值(最高优先级)   
#|       |
#|       |---默认的消息日志级别:将用该优先级来打印没有优先级的消息
#|
#|----控制台日志级别:优先级高于该值的消息将被打印至控制台

改变printk打印等级(需要管理员权限):修改后将dmesg中信息直接打印到串口中。

$ echo "7 4 1 7" > /proc/sys/kernel/printk

这四个值是在kernel/printk.c 中被定义:

int console_printk[4] = {
	CONSOLE_LOGLEVEL_DEFAULT,	/* console_loglevel */
	MESSAGE_LOGLEVEL_DEFAULT,	/* default_message_loglevel */
	CONSOLE_LOGLEVEL_MIN,		/* minimum_console_loglevel */
	CONSOLE_LOGLEVEL_DEFAULT,	/* default_console_loglevel */
};

内核中共提供了八种不同的日志级别,在 linux/kernel.h 中有相应的宏对应。

#define KERN_EMERG	    KERN_SOH "0"	/* system is unusable */
#define KERN_ALERT	    KERN_SOH "1"	/* action must be taken immediately */
#define KERN_CRIT	    KERN_SOH "2"	/* critical conditions */
#define KERN_ERR	    KERN_SOH "3"	/* error conditions */
#define KERN_WARNING	KERN_SOH "4"	/* warning conditions */
#define KERN_NOTICE	    KERN_SOH "5"	/* normal but significant condition */
#define KERN_INFO	    KERN_SOH "6"	/* informational */
#define KERN_DEBUG	    KERN_SOH "7"	/* debug-level messages */

#define KERN_DEFAULT	""		/* the default kernel loglevel */

  内核通过printk() 输出的信息具有日志级别,所以printk() 可以这样用:printk(KERN_INFO"Hello, world!\n");

未指定日志级别采用的默认级别是DEFAULT_MESSAGE_LOGLEVEL,该宏在kernel/printk.c 中被定义为整数4,即对应KERN_WARNING

#define default_message_loglevel (console_printk[1])

如果要想在内核启动过程中打印少的信息,就可以根据自己的需要在kernel/printk.c中修改以上数值(重新编译)。

/* printk's without a loglevel use this.. */
#define MESSAGE_LOGLEVEL_DEFAULT CONFIG_MESSAGE_LOGLEVEL_DEFAULT  #默认为0

2. 修改dmesg环形缓冲区大小

代码路径:/kernel/printk/printk.c

/* record buffer */
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
#define LOG_ALIGN 4
#else
#define LOG_ALIGN __alignof__(struct printk_log)
#endif
#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)            /*---->由此控制其缓冲区大小*/
static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);
static char *log_buf = __log_buf;
static u32 log_buf_len = __LOG_BUF_LEN;                      

/* Return log buffer address */
char *log_buf_addr_get(void)
{
	return log_buf;
}

  由以上可看出,dmesg缓冲区的大小由 CONFIG_LOG_BUF_SHIFT 控制,其规律为:size = 2 ^ CONFIG_LOG_BUF_SHIFT,因此修改这个宏就可以更改dmesg缓冲区的大小。

  这个宏在内核编译时由配置文件定义,如X86_64位的CPU配置文件路径为:\arch\x86\configs\x86_64_defconfig

...
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_LOG_BUF_SHIFT=18          ###########
CONFIG_CGROUPS=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CPUSETS=y
...

路虽远行则将至、事虽难做则必成
MrWang
<think>好的,我现在要解决用户的问题:在Linux中如何查看串口缓冲区的的大小。首先,我需要回忆一下Linux系统中与串口相关的配置和命令。 用户提到的是串口缓冲区大小,这可能涉及到驱动层面的设置或者系统级的配置。我记得在Linux中,串口设备通常位于/dev目录下,比如ttyS0、ttyUSB0等。每个串口设备都有对应的配置参数,比如波特率、数据位、停止位等,这些可以通过stty命令来设置或查看。但缓冲区大小可能不是直接通过stty来显示的,可能需要其他方法。 接下来,我想到Linux内核中的串口驱动可能会涉及缓冲区的大小设置。缓冲区分为输入缓冲区和输出缓冲区,可能分别有不同的参数。用户可能需要查看或调整这些缓冲区的大小。这时候,可能需要查看内核文档或者使用系统工具来获取这些信息。 然后,我回忆到sys文件系统(/sys)提供了许多内核参数和设备的详细信息。或许在/sys/class/tty/目录下,对应的串口设备子目录中会有相关的属性文件,比如buffer_size或者其他类似名称的文件。比如,检查/sys/class/tty/ttyS0/buffer_size这样的路径是否存在,这可能会显示当前缓冲区的大小。 另外,我记得有些资料提到,串口的缓冲区大小可能在内核编译时就已经确定,或者在模块加载时通过参数设置。如果是动态模块,可能需要使用modprobe命令加载时指定参数,或者在运行时通过ioctl调用来调整。不过用户的问题主要是查看当前缓冲区的大小,而不是修改它。 接下来,我需要验证这些方法是否有效。例如,使用stty命令查看串口参数,虽然stty -F /dev/ttyS0可能会显示一些配置,但不确定是否包括缓冲区大小。另外,检查sys目录下的文件是否有相关信息。可能需要实际测试或者查找相关文档。 此外,我还想到dmesg命令可能会在系统启动时显示串口驱动的初始化信息,其中可能包含缓冲区的分配情况。比如,通过dmesg | grep ttyS0查看相关日志,看是否有关于缓冲区大小的信息。 最后,可能需要参考内核文档或相关社区的资源,比如在线论坛或Stack Overflow上的讨论,确认在Linux查看串口缓冲区大小的标准方法。例如,是否有工具或文件直接提供这些信息,或者需要通过编程接口来获取。 总结起来,可能的步骤包括: 1. 检查sys文件系统中的相关属性文件。 2. 使用stty命令查看是否有相关参数。 3. 查看内核启动日志(dmesg)中的信息。 4. 参考内核文档或在线资源确认正确的方法。 可能需要结合这些方法,逐步排除并找到正确的查看方式。</think>在Linux系统中查看串口缓冲区大小的方法可通过以下步骤实现: --- ### **1. 查看串口驱动的缓冲区参数** Linux串口的输入/输出缓冲区大小通常由驱动定义。可通过以下方式查看相关参数: - 使用`sysfs`文件系统,在路径`/sys/class/tty/<串口设备>/device/driver`中查找缓冲区相关属性文件。例如: ```bash cat /sys/class/tty/ttyS0/buffer_size # 若存在该文件则直接显示缓冲区大小 ``` 注意:不同驱动可能暴露的参数名称不同,需根据实际硬件尝试[^3]。 --- ### **2. 使用`stty`命令查看配置** 虽然`stty`主要用于设置串口基本参数(如波特率),但可通过以下命令检查当前配置: ```bash stty -F /dev/ttyS0 # 替换为实际串口设备名 ``` 若输出包含`txqueuelen`字段,表示发送队列长度(与输出缓冲区相关),例如: ``` txqueuelen 4096 ``` --- ### **3. 分析内核日志** 通过`dmesg`查看驱动初始化时的缓冲区分配信息: ```bash dmesg | grep ttyS0 # 筛选目标串口设备的日志 ``` 若驱动在初始化时打印了缓冲区大小,例如: ``` serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A, buffer size 4096 ``` --- ### **4. 编程接口查询(高级)** 通过C语言程序调用`ioctl`接口获取缓冲区信息: ```c #include <termios.h> #include <stdio.h> #include <fcntl.h> int main() { int fd = open("/dev/ttyS0", O_RDWR); int buffer_size; ioctl(fd, TIOCOUTQ, &buffer_size); // 获取输出缓冲区当前数据量 printf("Output buffer used: %d bytes\n", buffer_size); close(fd); return 0; } ``` 注意:`TIOCOUTQ`返回的是当前输出缓冲区中未发送的数据量,而非总大小[^1]。 --- ### **总结** - **推荐方法**:优先尝试`sysfs`路径和`dmesg`日志。 - **默认值**:多数Linux发行版的串口缓冲区默认大小为`4096`字节,但可能因驱动不同而变化[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盗骊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值