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()
rename
hello\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;
}