【发布时间】:2016-03-23 13:45:47
【问题描述】:
我正在编写一个驱动程序作为模块。我必须从模块调用系统调用sys_epoll_create1()。我写了一个这样的模块:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/net.h>
#include <linux/syscalls.h>
#include <linux/eventpoll.h>
#include <net/sock.h>
MODULE_LICENSE("GPL");
static int hello_init(void)
{
sys_epoll_create1(1);
return 0;
}
static void hello_exit(void)
{
}
module_init(hello_init);
module_exit(hello_exit);
编译日志显示如下:
~/test $ make
make -C /lib/modules/4.2.0-16-generic/build M=/home/kyl/test modules
make[1]: Entering directory '/usr/src/linux-headers-4.2.0-16-generic'
CC [M] /home/kyl/test/hello.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: "sys_epoll_create1" [/home/kyl/test/hello.ko] undefined!
CC /home/kyl/test/hello.mod.o
LD [M] /home/kyl/test/hello.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.2.0-16-generic'
我检查过,linux/syscalls.h 中有一个 sys_epoll_create1() 的声明
asmlinkage long sys_epoll_create1(int flags);
我已经包含<linux/syscalls.h>作为头文件,为什么gcc仍然显示WARNING: "sys_epoll_create1" [/home/kyl/test/hello.ko] undefined!?
【问题讨论】:
-
您是否尝试修改内核代码以将此类系统调用导出到内核的其余部分?
-
@Claudio 那是我最后的选择。我更喜欢在不修改内核的情况下构建模块。
-
Linux 内核不再导出(
EXPORT_SYMBOL)系统调用实现(sys_*函数)。参见,例如,this question 关于sys_read和sys_open。与具有导出vfs_*替换的读/写文件不同,epoll相关函数不会为模块导出,因此您不能epoll_create1文件描述符并将其返回到用户。但是,如果您只想轮询内核中的一些文件集,有办法做到这一点。 -
@Tsyvarev 是否可以将
fs/eventpoll.c复制到我的模块源代码树中并使用重复的eventpoll.c构建? -
你可以试试,但 eventpoll 文件描述符中的循环检测将不起作用。实际上,在内核中使用 epoll 看起来很奇怪。但是,如果不了解您的最终目的,就很难提出建议。
标签: kernel linux-device-driver system-calls epoll