简体   繁体   English

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

[英]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: 以下是我的问题:

  1. 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

  2. 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

  3. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM