在Linux中的已注册字符设备中修改文件操作

时间:2019-07-07 12:24:30

标签: c linux-device-driver device-driver

对于某些硬件黑客攻击(如果需要,可以提供详细信息),我需要在正在使用的发行版中内置(不可加载)的内核模块中进行一些更改。出于可移植性的考虑,我希望避免使用自定义内核,甚至避免使用自定义配置。

我宁愿使用其他内核模块。但是,该模块是由另一个模块加载的(即,另一个模块调用了它的init_function)。

我需要更改的是实现file_operations的.write函数。

一种策略可能是取消注册chardev并在将自定义模块加载到内核后使用修改后的.write函数对其进行重新注册。 这是合法策略吗?周围是否有任何代码示例?

我想在drivers / media / rc / lirc_dev.c中更改以下行:

#define LIRCBUF_SIZE    256

#define LIRCBUF_SIZE    1024

基本上我需要更长的缓冲区,并避免在第330行附近出现EINVAL返回

if (count > LIRCBUF_SIZE || count % 2 == 0) {
  ret = -EINVAL;
  goto out_unlock;
}

lirc_dev正在注册字符设备/ dev / lirc0,/ dev / lirc1等,上面的行来自file_operations结构的.write实现。
看来,注册是由带有lirc_dev_init的rc_core模块触发的,我也想避免使用rc_core的自定义实现。

我已经在lirc用户空间工具中进行了自定义修改,该工具也对此缓冲区限制为256个单位(= int),但是在lirc驱动程序对“ /”进行“写入”时会中断dev / lirc0'设备出现输入输出错误。

基本上,写256个int块的策略是行得通的,但这很精致,由于时序问题,我认为我无法使其与硬件一起工作。 (何时“写入”内核空间实际上触发了一些硬件操作...)

如果我只想增加缓冲区,这一切似乎太复杂了……

1 个答案:

答案 0 :(得分:0)

“这是合法策略吗?” -不这是一个有趣的问题,但是我敢肯定这是不合法的。如果我了解您希望截获/ dev / lirc ?,则可以通过重写/ dev / lirc?的设备节点来实现,这很容易,我认为仍然是一回事。 / p>

传统UNIX设备节点包含两个数字,分别是大号和小号。当您打开(“ / dev / lirc2” ...)时,内核会检索主号码,并从映射表中检索设备实例。然后,它会在这种情况下调用方法以在设备上进行操作(打开,关闭,读取,写入,ioctl等)。

mknod实用程序可用于创建设备条目,因此我相信:

mv /dev/lirc2 /dev/olicr2 && mknod c /dev/lirc2 ${major} 2

将允许您将/ dev / lirc2重定向到新设备。

我遮盖了大约10章的细节;包括如何获取$ {major}的数字,我不确定无数的/ sys文件系统将如何应对这种滥用,但这导致了另一个问题:

为什么在lirc中需要更多的缓冲区空间?乍一看,似乎有一种更简单的方法来实现目标,而管道却少得多...