如何在Linux内核4.x中实现我自己的系统调用



我是内核新手,我想实现我自己的系统调用。我已经搜索了很多链接,几乎达到了,但仍然无法得到确切的输出。

我遵循自己的系统调用内核3.8.8 (youtube视频教程)。


我的设置是:
操作系统:ubuntu 14.04 LTS
拱:x86_64
我所遵循的程序是

  1. 编辑系统调用表linux-4.7/arch/x86/entry/syscals_64 .tbl
  2. 将原型添加到/usr/src/linux-4.7/include/linux
  3. 中的syscalls.h中
  4. 创建一个系统调用定义,并将系统调用目录添加到内核Makefile
  5. 编译内核并重启
  6. 编写一个用户应用程序来验证系统调用是否工作。

我可以通过syscall() api使用syscall num获得系统调用,但我想要的是传统的方式,如开放调用sys_open。我想像mycall需要调用sys_mycall

您可以编辑glibc以在系统调用周围添加包装器。类似的东西存在于系统调用中。列出glibc/sysdeps/unix中的文件(搜索您的平台)https://github.com/lattera/glibc/blob/master/sysdeps/unix/syscalls.listhttps://github.com/lattera/glibc/blob/master/sysdeps/unix/sysv/linux/x86_64/syscalls.list

# File name Caller  Syscall name    Args    Strong name Weak names
accept      -   accept      Ci:iBN  __libc_accept   accept
access      -   access      i:si    __access    access
close       -   close       Ci:i    __libc_close    __close close
open        -   open        Ci:siv  __libc_open __open open
read        -   read        Ci:ibn  __libc_read __read read
uname       -   uname       i:p __uname     uname
write       -   write       Ci:ibn  __libc_write    __write write

要解码此格式,请在处理此文件的脚本中使用"注释:sysdeps/unix/make-syscalls.sh.",正如https://blog.packagecloud.io/eng/2016/04/05/the-definitive-guide-to-linux-system-calls/

中建议的那样
# This script is used to process the syscall data encoded in the various
# syscalls.list files to produce thin assembly syscall wrappers around the
# appropriate OS syscall. See syscall-template.s for more details on the
# actual wrapper.
#
# Syscall Signature Prefixes:
#
# E: errno and return value are not set by the call
# V: errno is not set, but errno or zero (success) is returned from the call
#
# Syscall Signature Key Letters:
#
# a: unchecked address (e.g., 1st arg to mmap)
# b: non-NULL buffer (e.g., 2nd arg to read; return value from mmap)
# B: optionally-NULL buffer (e.g., 4th arg to getsockopt)
# f: buffer of 2 ints (e.g., 4th arg to socketpair)
# F: 3rd arg to fcntl
# i: scalar (any signedness & size: int, long, long long, enum, whatever)
# I: 3rd arg to ioctl
# n: scalar buffer length (e.g., 3rd arg to read)
# N: pointer to value/return scalar buffer length (e.g., 6th arg to recvfrom)
# p: non-NULL pointer to typed object (e.g., any non-void* arg)
# P: optionally-NULL pointer to typed object (e.g., 2nd argument to gettimeofday)
# s: non-NULL string (e.g., 1st arg to open)
# S: optionally-NULL string (e.g., 1st arg to acct)
# v: vararg scalar (e.g., optional 3rd arg to open)
# V: byte-per-page vector (3rd arg to mincore)
# W: wait status, optionally-NULL pointer to int (e.g., 2nd arg of wait4)

关于glibc系统调用包装器的更多信息,请访问官方网站:https://sourceware.org/glibc/wiki/SyscallWrappers

glibc使用三种类型的OS内核系统调用包装器:汇编、宏和定制。

装配系统调用在glibc中,简单的内核系统调用从名称列表转换为一个汇编包装器,然后编译. ...使用包装器的系统调用列表保存在系统调用中。列表文件:... ./sysdeps/unix/sysv/linux/x86_64/syscalls.list

不要忘记在linux头文件中为你的系统调用定义__NR号

有来自kernel.org(唯一的linux内核开发人员门户)或Documentation/addingsycalls的说明。*文件在Linux内核源代码:https://www.kernel.org/doc/html/v4.10/process/adding-syscalls.htmlhttps://github.com/torvalds/linux/blob/master/Documentation/process/adding-syscalls.rst

该方法在其他操作系统(如FreeBSD)上会有所不同:https://wiki.freebsd.org/AddingSyscalls

最新更新