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

我正在尝试写一个我自己的系统调用。 它只会返回当前时间。 我知道我应该做什么的概念,并且通过如下几个链接:

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

  • 另一个系统调用实现

但是我还是很困惑,没有得到理想的结果。 内核不编译,并由于问题而崩溃。 我已经在Debian最新的3.XX稳定版上试了一下

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

编辑

对于下面的答案 ,这里是我的问题:

  1. File 3: linux-xxx/arch/x86/kernel/syscall_table_32.S在我的linux文件夹中找不到。 我不得不临时凑合,修改了以下文件: linux-xxx/arch/x86/syscalls/syscall_64.tbl

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

  3. 内核映像编译成功,但我不能调用该函数。 它提供了一个undefined reference" error当我用gcc编译它为什么?

这只是一个例子,如何编写一个简单的内核系统调用。 考虑下面的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-xxx目录。

文件1:linux-xxx / test / system_strcpy.c在linux-xxx中创建一个名为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-xxx / test / Makefile在上面创建的同一个test目录中创建一个Makefile ,并将其放入:

obj-y := system_strcpy.o

文件3:linux-xxx / 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

process_vm_writev sys_process_vm_writev

312 64 kcmp sys_kcmp

system_strcpy system_strcpy

3.3版本的格式是: number abi name entry point

文件4:linux-xxx / 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-xxx / 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); (或者syscall(313,dest,src);对于内核3.3+),而不是常规的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不用像313等数字,也可以直接使用__NR_system_strcpy

这是一个通用的例子。 你将需要做一些实验来看看你的特定内核版本有什么作用。

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