我正在尝试使用 linux 内核 4.1.6 添加系统调用,但我能找到的所有文档都是针对旧版本的。有谁知道它在较新的内核中是如何完成的或者有任何好的参考资料?
应该有3个步骤:
添加到系统调用表中。我发现他们现在使用 arch/x86/syscalls/syscall_64.tbl 而不是entry.S。所以我在里面放了一些东西。
添加到 asm/unistd.h 文件。显然 unistd.h 文件现在是自动生成的,所以我们不必手动更新它?因此,由于该文件不存在,我对此步骤没有执行任何操作。 https://stackoverflow.com/questions/10988759/arch-x86-include-asm-unistd-h-vs-include-asm-generic-unistd-h
将系统调用编译到内核中。我已将实际的系统调用代码添加到 kernel/sys.c 中,正如基于内核 2.6 的书中所建议的那样(Robert Love 的 Linux 内核开发书)。我又重新编译了内核。
然后,我按照书中的建议编写了一个客户端程序,但当我尝试编译它时,它显示未知类型名称“helloworld”。我的程序与书上的不同,但结构是相同的。
#include <stdio.h>
#define __NR_helloworld 323
__syscall0(long, helloworld)
int main()
{
printf("I will now call helloworld syscall:\n");
helloworld();
return 0;
}
互联网(和可用的书籍)似乎严重缺乏这些信息 - 或者谷歌并不像它想象的那么聪明。无论如何,任何帮助都是值得赞赏的。
谢谢。 ~~~
答案1
根据_系统调用(2)手册页该_syscall0
宏可能已过时并且需要 #include <linux/unistd.h>
;事实上Linux 4.x没有它
但是,您可以安装musl-libc 库并使用其_syscall
功能。
你可以简单地使用间接系统调用(2)在您的用户代码中。所以你的测试程序是
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>
#define __NR_helloworld 323
static inline long mysys_helloworld(void) { return syscall(__NR_helloworld,NULL); }
int main (int argc, char**argv) {
printf("will do the helloworld syscall\n");
if (mysys_helloworld()) perror("helloworld");
return 0;
}
以上代码未经测试!
答案2
那么假设讲师希望人们阅读源代码,而不仅仅是从互联网上剪切和粘贴,这可以说是一个精心设计的作业。 (也就是说,Linux 内核代码不是很好读。请确保您知道如何使用 etag,因为通常您必须跟踪三个级别的宏才能了解发生了什么。)