从内核模块读取 dmesg

Posted

技术标签:

【中文标题】从内核模块读取 dmesg【英文标题】:Reading dmesg from a kernel module 【发布时间】:2012-07-30 11:34:47 【问题描述】:

我正在尝试从内核模块中简单地读取内核环形缓冲区。也称为 /proc/kmsg 和 dmesg 输出。

环顾四周,似乎对此的调用是 sys_syslog();从我读过的内容来看,dmesg 使用 syslog(),它使用位于 printk.c 中的 do_syslog()。

我搜索了一下,发现 do_syslog() 是在 linux/syslog.h 中定义的,所以我包含了这个文件。

在测试模块中对 do_syslog() 的实际调用如下所示:

read_bytes = do_syslog(2, temp_buffer, 1024, 0);

其中 temp_buffer 只是一个用于测试目的的 char temp_buffer[1024]。

程序可以编译,但是当我尝试加载模块时它失败了:

insmod:插入“testing.ko”时出错:模块中出现-1未知符号

从 dmesg 我看到:“未知符号 do_syslog (err 0)”

为什么这是一个未知符号?我需要链接一些东西吗?

makefile如下:

obj-m += testing.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

【问题讨论】:

【参考方案1】:

您需要使用导出的符号重新编译内核。

EXPORT_SYMBOL (do_syslog);

【讨论】:

谢谢!是否可以在不必重新编译内核的情况下做到这一点?当然,所有普通内核中都必须有一些标准功能来做到这一点?顺便说一句,我也得到了 sys_read() 和 sys_open() 的未知符号。 @csstudent2233:如果不导出符号是不可能的(如果你不考虑摆弄/dev/kmem)。不过,sys_readsys_open 应该已经导出了。

以上是关于从内核模块读取 dmesg的主要内容,如果未能解决你的问题,请参考以下文章

dmesg 简明笔记

Linux常用命令——dmesg

服务/软件管理:10---Linux的网卡(ethtool命令)

MIPS32路由器:module_init没有调用内核模块

Linux驱动之内核加载模块过程分析

linux加载与使用ko驱动