探索Linux内核的秘密:使用 dmesg 命令
dmesg 命令让你深入了解 Linux 启动过程中的隐藏世界。它就像一个“故障排除的朋友”,可以让你查看和监控来自内核自身环形缓冲区中的硬件设备和驱动程序的消息。
Linux的环形缓冲区的工作原理
在 Linux 和类 Unix 系统中,引导和启动是计算机开机时发生的两个不同阶段。
引导过程(通常涉及 BIOS 或 UEFI, MBR 和 GRUB)负责将系统初始化,直到内核加载到内存并连接到初始 ramdisk (initrd 或 initramfs), 然后系统初始化 完成。
接下来,启动进程接管,完成操作系统的初始化。在初始化的早期阶段,日志守护进程(如 syslog 或 rsyslog)尚未启动和运行。为了避免在此初始化阶段丢失重要的错误消息和警告,内核包含一个 环形缓冲区,作为消息的存储区域。
环形缓冲区是一个专门用于存储消息的内存区域。它的设计简洁,大小固定。当缓冲区满时,新消息会覆盖最旧的消息。从概念上讲,它可以被视为一个“循环缓冲区”。
内核环形缓冲区存储各种信息,例如设备驱动程序的初始化消息、来自硬件的消息和内核模块的消息。由于它包含这些低级别的启动消息,因此环形缓冲区是查找硬件错误或其他启动问题的好去处。
要查看这些消息,请使用 dmesg 命令。
dmesg 命令详解
dmesg 命令允许你 查看存储在环形缓冲区中的消息。默认情况下,你需要使用 sudo 权限才能执行 dmesg。
sudo dmesg
终端窗口中会显示环形缓冲区的所有消息。
这信息量太大了!我们需要将其通过管道传递给 less 以便更方便地查看:
sudo dmesg | less
现在你可以滚动浏览消息,查找感兴趣的内容。
你可以使用 less 的搜索功能来查找并高亮显示你感兴趣的项目和术语。在 less 中按下正斜杠键 “/” 即可启动搜索功能。
取消对 sudo 的依赖
如果你想避免每次使用 dmesg 时都使用 sudo,可以使用以下命令。 请注意:这将允许任何拥有你计算机用户帐户的人在不使用 sudo 的情况下使用 dmesg。
sudo sysctl -w kernel.dmesg_restrict=0
强制彩色输出
默认情况下,dmesg 可能被配置为产生彩色输出。 如果没有,你可以使用 `-L` (color) 选项来强制 dmesg 对其输出着色。
sudo dmesg -L
要让 dmesg 始终默认为彩色显示,请使用以下命令:
sudo dmesg --color=always
人性化的时间戳
默认情况下,dmesg 使用自内核启动以来的秒和 纳秒 作为时间戳。 要使其以更人性化的格式呈现,请使用 `-H` (human) 选项。
sudo dmesg -H
此操作会产生两个结果。
输出将自动在 less 中显示。
时间戳显示带有日期和时间的时间戳,精度为分钟。 每分钟发生的消息都标有从该分钟开始的秒数和纳秒数。
更易读的时间戳
如果你不需要纳秒级别的精度,但希望时间戳比默认值更容易阅读,请使用 `-T` (human-readable) 选项。(这有点令人困惑。`-H` 是 “human” 选项,`-T` 是 “human-readable” 选项。)
sudo dmesg -T
时间戳显示为标准日期和时间格式,但精度降低到分钟。
在一分钟内发生的所有事件都具有相同的时间戳。 如果你只关心事件的顺序,这已经足够了。 另外,请注意,你将直接返回到命令提示符。此选项不会自动调用 less。
实时查看消息
要查看实时到达内核环形缓冲区的消息,请使用 `–follow`(等待消息)选项。这可能看起来有些奇怪。如果环形缓冲区用于存储启动序列期间发生的事件的消息,那么计算机启动并运行后,实时消息是如何到达环形缓冲区的?
任何导致连接到计算机的硬件发生变化的操作都会导致消息被发送到内核环形缓冲区。 更新或添加内核模块时,你将看到关于这些更改的环形缓冲区消息。 如果你插入 USB 驱动器或连接或断开蓝牙设备,你将在 dmesg 输出中看到消息。 甚至虚拟硬件也会导致新消息出现在环形缓冲区中。 启动虚拟机,你将看到新信息到达环形缓冲区。
sudo dmesg --follow
请注意,你不会返回到命令提示符。 当新消息出现时,它们会由终端窗口底部的 dmesg 显示。
甚至安装 CD-ROM 光盘也被视为一种更改,因为它会将 CD-ROM 光盘的内容挂载到目录树上。
要退出实时提要,请按 `Ctrl+C`。
获取最后十条消息
使用 `tail` 命令 获取最后十条 内核环形缓冲区消息。 当然,你可以获取任意数量的消息。 这里以十条为例。
sudo dmesg | tail -10
最后十条消息被提取并在终端窗口中列出。
搜索特定术语
通过管道将 dmesg 的输出传递给 `grep`,你可以 搜索特定的字符串或模式。这里我们使用 `-i` (忽略大小写)选项,以便忽略匹配字符串的大小写。 我们的结果将包括“usb”和“USB”,以及小写和大写的其他任何组合。
sudo dmesg | grep -i usb
高亮显示的搜索结果包含大写和小写字母。
我们可以隔离包含对系统 sda 上的第一个硬盘的引用的消息。 (实际上,sda 现在也用于 第一个 SATA 硬盘,以及 USB 驱动器。)
sudo dmesg | grep -i sda
所有提及 sda 的消息都被检索并列在终端窗口中。
要让 `grep` 一次搜索多个术语,请使用 `-E` (扩展正则表达式)选项。你必须使用管道符 “|” 在带引号的字符串中提供搜索词搜索词之间的分隔符:
sudo dmesg | grep -E "memory|tty|dma"
任何提及任何搜索词的消息都会在终端窗口中列出。
使用日志级别
记录到内核环形缓冲区的每条消息都附加了一个级别。 级别代表消息中信息的重要性。 级别包括:
emerg
:系统不可用。
alert
:必须立即采取措施。
crit
:临界条件。
err
:错误条件。
warn
:警告条件。
notice
:正常但重要的情况。
info
:信息。
debug
:调试级别的消息。
我们可以使用 dmesg 提取与特定级别匹配的消息,方法是使用 `-l`(level)选项并将级别名称作为命令行参数传递。 要仅查看 “info” 级别的消息,请使用以下命令:
sudo dmesg -l info
列出的所有消息都是参考消息。 它们不包含错误或警告,只是有用的通知。
在一个命令中组合两个或多个日志级别,以获取多个日志级别的消息:
sudo dmesg -l debug,notice
dmesg 的输出是每个日志级别的消息的混合:
设备类别
dmesg 消息被分为称为 “facility” 的类别。 设备列表如下:
kern |
内核消息。 |
user |
用户级消息。 |
mail |
邮件系统。 |
daemon |
系统守护进程。 |
auth |
安全/授权消息。 |
syslog |
内部 syslogd 消息。 |
lpr |
行式打印机子系统。 |
news |
网络新闻子系统。 |
我们可以让 dmesg 过滤其输出,以便仅显示特定设备中的消息。 为此,我们必须使用 `-f` (facility) 选项:
sudo dmesg -f daemon
dmesg 会列出终端窗口中与守护进程相关的所有消息。
正如我们对级别所做的那样,我们可以要求 dmesg 一次列出来自多个设备的消息:
sudo dmesg -f syslog, daemon
输出是系统日志和守护进程日志消息的混合。
组合设备和级别
`-x` (解码)选项使 dmesg 将设备和级别显示为每一行的人性化可读前缀。
sudo dmesg -x
设备和级别可以在每行的开头看到:
第一个高亮部分是来自 “内核” 设备的,级别为 “通知” 的消息。第二个高亮部分是来自 “内核” 设备,级别为 “信息” 的消息。
为什么要使用 dmesg?
简而言之,用于故障排除。
如果你遇到某个硬件无法识别或行为异常的问题,dmesg 可能会提供线索。
使用 dmesg 查看从最高级别到每个较低级别的消息,查找提及硬件项目或可能与问题相关的任何错误或警告。
使用 dmesg 搜索与适当设备相关的内容,以查看它们是否包含任何有用的信息。
通过管道将 dmesg 传递给 grep,并查找相关字符串或标识符,例如产品制造商或型号。
通过管道将 dmesg 传递给 grep,并查找诸如 “gpu” 或 “storage” 之类的通用术语,或诸如 “failure”, “failed” 或 “unable” 之类的术语。
使用 `–follow` 选项并实时查看 dmesg 消息。
祝你狩猎愉快!