C 如何将自定义系统调用与其名称而非号码一起使用
可能我混淆了一些概念,但我有一个问题: 要使用我的系统调用,我运行以下代码:C 如何将自定义系统调用与其名称而非号码一起使用,c,linux-kernel,C,Linux Kernel,可能我混淆了一些概念,但我有一个问题: 要使用我的系统调用,我运行以下代码: #include <stdio.h> #include <linux/kernel.h> #include <sys/syscall.h> #include <unistd.h> #define __NR_hello 337 long hello_syscall(void) { return syscall(__NR_hello); } int mai
#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>
#define __NR_hello 337
long hello_syscall(void) {
return syscall(__NR_hello);
}
int main(int argc, char *argv[]) {
long int a = hello_syscall();
printf(“System call returned %ld\n”, a);
return 0;
}
#包括
#包括
#包括
#包括
#定义\uuuunr\uHello 337
长hello_系统调用(void){
返回系统调用(\uuuunr\uhello);
}
intmain(intargc,char*argv[]){
long int a=hello_syscall();
printf(“系统调用返回%ld\n”,a);
返回0;
}
这样,它就可以工作了!但是,如果我想做下面这样的事情,只使用系统调用名而不使用号码定义,等等,该怎么办
#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
long int a = hello();
printf(“System call returned %ld\n”, a);
return 0;
}
#包括
#包括
#包括
#包括
intmain(intargc,char*argv[]){
long int a=hello();
printf(“系统调用返回%ld\n”,a);
返回0;
}
是否必须包含自定义头文件?在大多数情况下,系统调用将通过处理软件中断来实现。这个触发的中断将控制系统调用处理程序,该处理程序将根据系统调用id决定必须调用哪个函数来处理该特定中断 下面是osdev.org上的一个小例子(请参阅): 基本上是这样的:
int syscall(int syscall_id)
{
if ( syscall_id == SYSCALL_READ ) {
return read();
}
else if ( syscall_id == SYSCALL_WRITE )
return write();
}
return SYSCALL_ERROR;
}
因此,您必须始终在某个时候向内核提供这些功能。所有系统调用都是按您的方式调用的 唯一的区别是包装器(作为您为自己的系统调用提供的
hello\u syscall()
)是链接到您的程序的一些lib的一部分,使用libc时每个默认值都有很多
为了能够简单地调用hello()
renamehello\u syscall
到hello
,将它放在一个库中,并将这个库链接到您的程序。没有自动为你做这件事
您永远不会直接调用内核
要了解如何对其他系统调用执行此操作,请查看您最喜欢的libc实现的源代码
更新:
如果可能,将附加的系统调用放入模块中。这使您不必首先修补内核以使系统调用可用。我不熟悉linux内核,但如果只是重命名/重写
long hello_syscall(void){return syscall(u NR_hello);}
到long hello(void){return syscall(337)}
,当然!但我的目标是不要使用数字!我只想写系统调用名,代码必须自动理解哪个是相关的数字,可能是使用头文件,或者其他你为什么说“不使用该数字”?因为在编译新内核之前,我将自定义系统调用的数字放在unistd.h文件和syscalls.h文件中。现在,我希望我可以在测试文件中使用系统调用名与其编号之间的关系。如果我必须将我的定制内核交付给我的朋友,我希望他能够只使用系统调用名称而不知道其编号(不要担心;)我希望自定义系统调用的编号对可能的客户机是透明的,并且他只知道系统调用名称。所以,是否没有办法直接使用我在unistd.h和syscall_table_32.S中输入的名称来代替它的编号?不,没有。因为没有系统调用。只有将自己的包装器添加到自己的程序、库或任何其他库中,才能调用它。不过,我不会“破坏”系统头或修补系统库。提供您自己的标题以及您自己的库,以及提供系统调用的模块。好的,太好了!还有一个小问题,现在我已经创建了一个头文件,在其中我放置了方法syscall(_NR_hello)来调用代码,您知道如何将这个头文件直接包含在内核中吗?谢谢你的时间!我将不讨论内核,因为它是系统调用的用户空间接口。您可以将其放入/usr/include//hello.h
调用系统调用(\uu NR\u hello)
(通常称为hello
)的函数将被编译成一个名为libyourlibname.so.x.y.z
的库,并可能转到/usr/lib
。好的,我已经理解了逻辑,因此,要使用系统调用名,我必须编写一个伪汇编文件,就像您发布的第一个文件一样?不,不,这只是一个示例,向您展示了内核总是必须根据ID之类的东西来决定调用哪个函数。我的意思是。。既然您已经获得了内核的源代码,您就可以查找发生这种情况的位置,但我认为这不是一项简单的任务。您的朋友不必知道或使用系统调用的号码,因为它已被hello()
隐藏。
int syscall(int syscall_id)
{
if ( syscall_id == SYSCALL_READ ) {
return read();
}
else if ( syscall_id == SYSCALL_WRITE )
return write();
}
return SYSCALL_ERROR;
}