c-如何在debian/ubuntu上编写系统调用



我正在尝试编写自己的系统调用。它只会返回当前时间。我知道我应该做什么的概念,我确实经历了几个这样的链接:

  • 在Linux 2.6 for i386上实现系统调用

  • 另一个系统调用实现

但我仍然很困惑,没有得到想要的结果。内核没有进行编译,并且由于问题而崩溃。我已经在debian上试用了3.X.X 的最新稳定版本

有人能给我指一个干净的hello world类型的程序来开发系统调用吗?

编辑

对于以下答案,以下是我的问题:

在我的linux文件夹中找不到
  1. File 3: linux-x.x.x/arch/x86/kernel/syscall_table_32.S。我不得不即兴创作,因此修改了以下文件:linux-x.x.x/arch/x86/syscalls/syscall_64.tbl

  2. 上面提到的(1)个新文件具有不同的<number> <64/x32/common> <name> <entry point>模式,我的条目是"313常见">

  3. 内核映像确实编译成功,但我无法调用该函数。当我用gcc编译它时,它给出了一个undefined reference" error。为什么?

这只是如何编写简单内核系统调用的示例。考虑下面的C函数system_strcpy(),它只是将一个字符串复制到另一个字符串中:类似于strcpy()的作用。

#include<stdio.h>
long system_strcpy(char* dest, const char* src)
{
int i=0;
while(src[i]!=0)
dest[i]=src[i++];
dest[i]=0;
return i;
}

在编写之前,获取一个内核源代码tar并对其进行解压缩,以获得一个linux-x.x.x.目录。

文件1:linux-x.x.x/test/system_strcpy.c在linux-x.x.x中创建一个名为test的目录,并将此代码保存为其中的文件system_strcpy.c

#include<linux/linkage.h>
#include<linux/kernel.h>
asmlinkage long system_strcpy(char*dest, const char* src)
{
int i=0;
while(src[i]!=0)
dest[i]=src[i++];
dest[i]=0;
return i;
}

文件2:linux-x.x.x/test/Makefile在上面创建的test目录中创建一个Makefile,并在其中放入此行:

obj-y := system_strcpy.o

文件3:linux-x.x.x/arch/x86/kernel/syscall_table_32.S现在,您必须将系统调用添加到系统调用表中。在文件中附加以下行:

.long system_strcpy

注意:对于内核3.3及更高版本

*请参阅:linux-3.3.xx/arch/x86/syscalls/syscall_64.tbl*

在那里,现在在下面一系列行的末尾添加:

310 64进程_vm_readv系统_进程_vm_readv

311 64进程_vm_writev系统_进程_vm_writev

312 64 kcmp系统_kcmp

313 64 system_strcpy system_strcopy

3.3版本的格式为:numberabinameentry point

文件4:linux-x.x.x/arch/x86/include/asm/unistd_32.h

注意:此部分对于3.3及更高版本的内核是多余的

在该文件中,所有系统调用的名称都将与一个唯一的号码相关联。在最后一个系统呼叫号码对之后,添加一条线路

#define __NR_system_strcpy 338

(如果337是与系统呼叫号码对中的最后一个系统呼叫相关联的号码)。

然后将NR_syscalls值替换为(现有数字增加1),说明系统调用的总数,即在这种情况下,NR_syscalls应该是338,而新值是339。

#define NR_syscalls 339

文件5:linux-x.x.x/include/linux/syscalls.h

将我们函数的原型附加到文件中。

asmlinkage long system_strcpy(char *dest,char *src);

就在文件中CCD_ 21行之前。

文件6:在源目录的根目录下创建文件

打开Makefile,找到定义core-y的行,并将目录test添加到该行的末尾。

core-y += kernel/ mm/ fs/ test/

现在编译内核。问题:make bzImage -j4

通过以root用户身份(或使用root权限)执行以下命令来安装内核:make install

重新启动系统。

要使用最近创建的系统调用,请使用:

syscall(338,dest,src);(或内核3.3+的syscall(313,dest,src);),而不是常规的strcpy库函数。

#include "unistd.h"
#include "sys/syscall.h"
int main()
{
char *dest=NULL,*src="Hello";
dest=(char*)malloc(strlen(src)+1);
syscall(338,dest,src);//syscall(313,dest,src); for kernel 3.3+
printf("%s n %sn",src,dest);
return 0;
}

代替syscall中的313等数字,您也可以直接使用__NR_system_strcpy

这是一个通用的例子。您需要做一些实验,看看什么适用于您的特定内核版本。

上述答案不适用于内核3.5.0和3.7.6,产生未定义的引用编译错误。为了解决这个问题,应该在system_strcpy.c中包含linux/syscalls.h,而不是linux/linking.h。此外,最好使用SYSCALL_DEFINE2(strcpy,dest,src)来定义系统调用。

相关内容

最新更新