简单系统调用实现示例?

mms*_*swe 0 operating-system kernel system

有趣的是,我在网上找不到任何简单的例子.你能分享一个简单的例子吗?我试图通过分析一个例子来理解以下内容.

?   Typically, 
?   a number associated with each system call
?   Number used as an index to a table: System Call table
?   Table keeps addresses of system calls (routines)
?   System call runs and returns
?   Caller does not know system call implementation
?   Just knows interface
Run Code Online (Sandbox Code Playgroud)

mau*_*zel 6

这取决于您要为其添加系统调用的体系结构,或者是否要为所有体系结构添加系统调用.我将解释一种为ARM添加系统调用的方法.

  1. 选择系统调用的名称.例如,mysyscall.
  2. 选择一个系统调用号码.arch/arm/include/asm/unistd.h,请注意每个系统调用如何__NR__SYSCALL_BASE+<number>分配给它的特定数字().为系统调用选择一个未使用的号码.让我们选择系统调用号码223.然后添加:

    #define __NR_mysyscall (__NR_SYSCALL_BASE+223

    索引223将在该头文件中.这会将数字223分配给ARM体系结构上的系统调用.

  3. 修改特定于体系结构的系统调用表.在linux/arch/arm/kernel/calls.S,将与syscall 223对应的行更改为:

    CALL(sys_mysyscall)

  4. 添加你的函数原型.假设您要添加非体系结构特定的系统调用.编辑文件:include/linux/syscalls.h并添加您的系统调用原型:

    asmlinkage long sys_mysyscall(struct dummy_struct *buf);

    如果您想专门为ARM添加它,请在此文件中执行以下操作:arch/arm/kernel/sys_arm.c.

  5. 在某个地方实现你的系统调用.随时创建一个文件.例如,在kernel/目录中.你至少需要:

#include <linux/syscalls.h>
...
SYSCALL_DEFINE1(mysyscall, struct dummy_struct __user *, buf)
{
    /* Implement your syscall */
}
Run Code Online (Sandbox Code Playgroud)

注意宏,SYSCALL_DEFINE1.末尾的数字应与系统调用的输入参数对应.在这种情况下,我们的系统调用只有1个参数,所以你使用SYSCALL_DEFINE1.如果它有两个参数,你会使用SYSCALL_DEFINE2,等等.

不要忘记将对象(.o)文件添加到放置它的目录中的Makefile.

  1. 编译新内核并进行测试.您尚未修改C库,因此无法使用调用系统调用mysyscall().您需要使用syscall()以系统调用号作为第一个参数的函数:
struct dummy_struct *buf = calloc(1, sizeof(buf));   
int res = syscall(223, buf);
Run Code Online (Sandbox Code Playgroud)

请注意,这是针对ARM的.对于其他架构,该过程将非常相似.

编辑:不要忘记将您的系统调用文件添加到kernel /中的Makefile.