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

时间:2012-09-18 03:03:47

标签: c ubuntu linux-kernel debian recovery

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

但我仍然感到困惑,并没有得到理想的结果。内核没有编译,并且由于问题导致崩溃。我在debian最新稳定版本的3.X.X

上试过了

有人可以指出一个干净的hello world程序来开发系统调用吗?

修改

below answer,这是我的问题:

    在我的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。为什么呢?

2 个答案:

答案 0 :(得分:7)

这只是如何编写简单内核系统调用的示例。 考虑以下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 在您在上面创建的同一个Makefile目录中创建一个test并将此行放入其中:

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 /拱/ 86 /系统调用/ syscall_64.tbl *

在那里,现在添加到以下系列行的末尾:

310 64 process_vm_readv sys_process_vm_readv

311 64 process_vm_writev sys_process_vm_writev

312 64 kcmp sys_kcmp

313 64 system_strcpy system_strcpy

3.3版本的格式为: number abi name entry 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. / p>

#define NR_syscalls 339

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

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

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

就在文件中的#endif行之前。

文件6:Makefile位于源目录的根目录。

打开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 %s\n",src,dest);
 return 0;
}

您可以直接使用syscall

而不是__NR_system_strcpy中的313等数字

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

答案 1 :(得分:4)

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