2

我正在尝试制作一个在 2.6.32 内核上工作的内核模块以在 3.6 内核上工作。我们使用 IOCTL 调用来更新 Linux 内核模块中的结构。这些调用在 2.6.32 内核中运行良好。

当我在 3.6 内核中尝试相同的操作时,只要从用户空间应用程序进行 ioctl 调用,我就会面临内核挂起。它是基于套接字的接口而不是基于文件的接口,因此我们使用 struct proto_ops 下的 ioctl。

由于没有生成核心转储,我该如何调试这种情况。要从用户空间复制数据,我正在使用 copy_from_user 命令。

调试此方案的任何指针都会非常有帮助

4

1 回答 1

1

ioctl() 是内核的剩余部分之一,在大内核锁 (BKL) 下运行。过去,BKL 的使用使得长时间运行的 ioctl() 方法可以为不相关的进程创建较长的延迟。

以下是对将 unlocked_ioctl 和 compat_ioctl 引入 2.6.11 的补丁的解释。ioctl 字段的删除发生在很久以后,在 2.6.36 中。

解释:执行 ioctl 时,它占用了Big Kernel Lock (BKL),因此不能同时执行其他任何操作。这在多处理器机器上是非常糟糕的,因此需要付出很大的努力来摆脱 BKL。首先,引入了 unlocked_ioctl。它允许每个驱动程序编写者选择使用什么锁。这可能很困难,因此有一段时间旧驱动程序仍然可以工作(使用 ioctl),但新驱动程序可以使用改进的接口(unlocked_ioctl)。最终,所有驱动程序都被转换,并且可以删除 ioctl。

compat_ioctl 实际上是不相关的,即使它是同时添加的。其目的是允许 32 位用户态程序在 64 位内核上进行 ioctl 调用。ioctl 的最后一个参数的含义取决于驱动程序,因此无法进行与驱动程序无关的转换。

参考:Jonathan Corbetioctl() 新方法

于 2018-03-27T06:43:03.603 回答