[英]How to write system calls on debian/ubuntu
I am trying to write a system call of my own. 我正在尝试编写自己的系统调用。 It would just return the current time.
它只会返回当前时间。 I know the concept of what should I do and I did go through a couple of links like these:
我知道应该做什么的概念,我确实经历了以下几个链接:
But I am still confused and have not got the desired result. 但我仍然感到困惑,并没有得到预期的结果。 The kernel is not compiling and its crashing due to problems.
内核没有编译,并且由于问题导致崩溃。 I have tried it on debian latest stable release of 3.XX
我在debian最新稳定版3.XX上尝试过它
Could someone point me out to a clean hello world
kind of program to develop system calls? 有人能指出我一个干净的
hello world
程序来开发系统调用吗?
EDIT 编辑
To the below answer , here are my problems: 以下是我的问题:
File 3: linux-xxx/arch/x86/kernel/syscall_table_32.S
is not found in my linux folder. File 3: linux-xxx/arch/x86/kernel/syscall_table_32.S
在我的linux文件夹中找不到File 3: linux-xxx/arch/x86/kernel/syscall_table_32.S
。 I had to improvise and so modified the following file: linux-xxx/arch/x86/syscalls/syscall_64.tbl
我不得不即兴创作并修改了以下文件:
linux-xxx/arch/x86/syscalls/syscall_64.tbl
The above (1) new file mentioned had different pattern of <number> <64/x32/common> <name> <entry point>
and my entry was `313 common 上面提到的(1)新文件有不同的
<number> <64/x32/common> <name> <entry point>
,我的条目是``313 common
The kernel image did compile successfully, but I couldnt call the function. 内核映像已成功编译,但我无法调用该函数。 It gives an
undefined reference" error
when i compile it with gcc. Why? 当我用gcc编译时,它给出了一个
undefined reference" error
。为什么?
This is just example how to write a simple kernel system call. 这只是如何编写简单内核系统调用的示例。 Consider the following C function system_strcpy() that simply copies one string into another: similar to what strcpy() does.
考虑以下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;
}
Before writing, get a kernel source tar and untar it to get a linux-xxx directory. 在编写之前,获取内核源代码tar并解压缩以获取linux-xxx目录。
File 1: linux-xxx/test/system_strcpy.c Create a directory within the linux-xxx, named test
and save this code as file system_strcpy.c
in it. 文件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;
}
File 2: linux-xxx/test/Makefile Create a Makefile
within the same test
directory you created above and put this line in it: 文件2:linux-xxx / test / Makefile在上面创建的同一个
test
目录中创建一个Makefile
,并在其中加入以下行:
obj-y := system_strcpy.o
File 3: linux-xxx/arch/x86/kernel/syscall_table_32.S Now, you have to add your system call to the system call table. 文件3:linux-xxx / arch / x86 / kernel / syscall_table_32.S现在,您必须将系统调用添加到系统调用表中。 Append to the file the following line:
在文件中附加以下行:
.long system_strcpy
NOTE: For Kernel 3.3 and higher versions. 注意:对于内核3.3及更高版本。
*Refer:linux-3.3.xx/arch/x86/syscalls/syscall_64.tbl* *请参阅:Linux的3.3.xx /弓/ 86 /系统调用/ syscall_64.tbl *
And in there, now add at the end of the following series of lines: 在那里,现在添加到以下系列行的末尾:
310 64 process_vm_readv sys_process_vm_readv 310 64 process_vm_readv sys_process_vm_readv
311 64 process_vm_writev sys_process_vm_writev 311 64 process_vm_writev sys_process_vm_writev
312 64 kcmp sys_kcmp 312 64 kcmp sys_kcmp
313 64 system_strcpy system_strcpy 313 64 system_strcpy system_strcpy
The format for the 3.3 version is in: number
abi
name
entry point
3.3版本的格式为:
number
abi
name
entry point
File 4: linux-xxx/arch/x86/include/asm/unistd_32.h 文件4:linux-xxx / arch / x86 / include / asm / unistd_32.h
NOTE: This section is redundant for 3.3 and higher kernel versions 注意:对于3.3及更高版本的内核版本,此部分是冗余的
In this file, the names of all the system calls will be associated with a unique number. 在此文件中,所有系统调用的名称将与唯一编号相关联。 After the last system call-number pair, add a line
在最后一个系统调用号对后,添加一行
#define __NR_system_strcpy 338
(if 337 was the number associated with the last system call in the system call-number pair). (如果337是与系统呼叫号码对中的最后一次系统调用相关联的号码)。
Then replace NR_syscalls
value, stating total number of system calls with (the existing number incremented by 1) ie in this case the NR_syscalls
should've been 338 and the new value is 339. 然后替换
NR_syscalls
值,说明系统调用的总数(现有数字加1),即在这种情况下, NR_syscalls
应该是338,新值是339。
#define NR_syscalls 339
File 5: linux-xxx/include/linux/syscalls.h 文件5:linux-xxx / include / linux / syscalls.h
Append to the file the prototype of our function. 在文件中附加我们函数的原型。
asmlinkage long system_strcpy(char *dest,char *src);
just before the #endif
line in the file. 就在文件中的
#endif
行之前。
File 6: Makefile at the root of source directory. 文件6:Makefile位于源目录的根目录。
Open Makefile
and find the line where core-y
is defined and add the directory test
to the end of that line. 打开
Makefile
并找到定义core-y
的行,并将目录test
添加到该行的末尾。
core-y += kernel/ mm/ fs/ test/
Now compile the kernel. 现在编译内核。 Issue:
make bzImage -j4
问题:
make bzImage -j4
Install the kernel by executing the following command as root(or with root permissions): make install
通过以root用户身份执行以下命令来安装内核(或使用root权限):
make install
Reboot the system. 重新启动系统。
To use the recently created system call use: 要使用最近创建的系统调用,请使用:
syscall(338,dest,src);
(or syscall(313,dest,src);
for kernel 3.3+) instead of the regular strcpy
library function. (或
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;
}
Instead of numbers like 313,etc in syscall
, you can also directly use __NR_system_strcpy
您可以直接使用
__NR_system_strcpy
而不是syscall
313等数字
This is a generic example. 这是一个通用的例子。 You will need to do a little experimentation to see what works for your specific kernel version.
您需要做一些实验,看看哪些适用于您的特定内核版本。
The above answer does not work for kernel 3.5.0 and 3.7.6, producing undefined reference compiling error. 上面的答案不适用于内核3.5.0和3.7.6,产生未定义的引用编译错误。 To fix the problem linux/syscalls.h should be included in system_strcpy.c instead of linux/linkage.h.
要解决这个问题,linux / syscalls.h应该包含在system_strcpy.c而不是linux / linkage.h中。 Also, it's better to use SYSCALL_DEFINE2(strcpy, dest, src) to define a system call.
此外,最好使用SYSCALL_DEFINE2(strcpy,dest,src)来定义系统调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.