我正在尝试编写自己的系统调用。它只会返回当前时间。我知道应该做什么的概念,我确实经历过以下几个链接:
但我仍然感到困惑,并没有得到理想的结果。内核没有编译,并且由于问题导致崩溃。我在debian最新稳定版本的3.X.X
上试过了有人可以指出一个干净的hello world
程序来开发系统调用吗?
修改
到below answer,这是我的问题:
File 3: linux-x.x.x/arch/x86/kernel/syscall_table_32.S
。我不得不即兴创作并修改了以下文件:linux-x.x.x/arch/x86/syscalls/syscall_64.tbl
上面提到的(1)新文件有<number> <64/x32/common> <name> <entry point>
的不同模式,我的条目是'313常见
内核映像编译成功,但我无法调用该函数。当我用gcc编译它时,它给出undefined reference" error
。为什么呢?
答案 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)来定义系统调用。